PHP脚本调用curl与jq命令无输出问题求助
问题分析与解决办法
看起来你的PHP脚本没输出主要踩了几个shell_exec使用的常见坑,咱们逐个排查:
1. 变量定义的语法错误
你脚本里的$doi = someDOIvalue;这里,如果someDOIvalue是具体的DOI字符串(比如10.1016/someDOIvalue),必须用引号包裹,否则PHP会把它当成未定义的常量,触发警告甚至中断执行:
// 正确写法,用单引号或双引号包裹字符串 $doi = '10.1016/someDOIvalue';
2. shell_exec默认吞掉了错误输出
shell_exec只返回命令的标准输出(stdout),如果命令执行出错(比如jq没安装、curl请求失败、命令路径找不到),错误信息会输出到标准错误(stderr),你根本看不到。要捕获错误,需要把stderr重定向到stdout:
// 在命令末尾加上 2>&1,把错误输出合并到标准输出 $cmd = $query.$doi." | jq '.title' 2>&1";
这样如果命令有问题,$title里会包含错误信息,就能快速定位故障点。
3. PHP运行环境的PATH和命令行不一致
你在命令行能正常运行的命令,PHP的web环境(比如Apache、php-fpm)可能找不到——因为二者的PATH环境变量不一样。比如jq可能不在PHP的PATH搜索范围内,最好用绝对路径调用命令:
# 先在命令行查curl和jq的绝对路径 which curl # 比如输出 /usr/bin/curl which jq # 比如输出 /usr/bin/jq
然后把脚本里的命令换成绝对路径:
$query = '/usr/bin/curl -LH "Accept: application/json" http://doi.org/'; $cmd = $query.$doi." | /usr/bin/jq '.title' 2>&1";
4. 变量转义与命令注入风险
虽然你命令行里的写法没问题,但直接拼接变量到shell命令里可能会遇到特殊字符解析问题,还存在命令注入风险。建议用escapeshellarg转义DOI变量:
$escaped_doi = escapeshellarg($doi); $query = '/usr/bin/curl -LH "Accept: application/json" http://doi.org/'.$escaped_doi; $cmd = $query." | /usr/bin/jq '.title' 2>&1";
分步测试建议
先简化脚本,一步步排查问题:
<?php echo "Starting test<br>"; $doi = '10.1016/someDOIvalue'; // 替换成真实可访问的DOI echo 'DOI: '.$doi.'<br>'; // 先单独测试curl命令 $curl_cmd = '/usr/bin/curl -LH "Accept: application/json" http://doi.org/'.$doi.' 2>&1'; echo 'Curl command: '.$curl_cmd.'<br>'; $curl_output = shell_exec($curl_cmd); echo 'Curl output:<br>'.$curl_output.'<br>'; // 再测试加jq的完整命令 $cmd = $curl_cmd." | /usr/bin/jq '.title' 2>&1"; echo 'Full command: '.$cmd.'<br>'; $title = shell_exec($cmd); echo 'Title:<br>'.$title; ?>
这样能清晰看到是curl请求出问题,还是jq解析有问题,或是PHP环境的配置问题。
内容的提问来源于stack exchange,提问作者ohMMM
相关产品推荐
相关产品推荐

