【问题标题】:PHP shell_exec with a command does not behave the same way as when it is executed through the terminal带有命令的 PHP shell_exec 的行为方式与通过终端执行时不同
【发布时间】:2021-08-17 06:57:46
【问题描述】:

当我在 macOS 10.13 终端上执行以下命令时:

curl 'https://api.perlego.com/metadata/v2/metadata/books/toc/682348' \
> -XGET \
> -H 'Origin: https://www.perlego.com' \
> -H 'Host: api.perlego.com' \
> -H 'Accept: application/json' \
> -H 'Connection: keep-alive' \
> -H 'Accept-Language: en-sg' \
> -H 'Accept-Encoding: br, gzip, deflate' \
> -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.1.2 Safari/605.1.15' \
> -H 'Referer: https://www.perlego.com/book/682348/10-human-how-your-bodys-microbes-hold-the-key-to-health-and-happiness-pdf' --compressed | brotli -d > temp.txt

这是输出:

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   535    0   535    0     0   1433      0 --:--:-- --:--:-- --:--:--  1430

我看到一个文件 temp.txt 保存到目录中,其中包含我需要的数据(一个 json)。

但是当我通过 PHP 执行这个时:

$comd = <<<EOT
cd "/Users/user/Documents/RU_general"; curl 'https://api.perlego.com/metadata/v2/metadata/books/toc/682348' \
-XGET \
-H 'Origin: https://www.perlego.com' \
-H 'Host: api.perlego.com' \
-H 'Accept: application/json' \
-H 'Connection: keep-alive' \
-H 'Accept-Language: en-sg' \
-H 'Accept-Encoding: br, gzip, deflate' \
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.1.2 Safari/605.1.15' \
-H 'Referer: https://www.perlego.com/book/682348/10-human-how-your-bodys-microbes-hold-the-key-to-health-and-happiness-pdf' --compressed | brotli -d > temp.txt
EOT;

d($comd);
$res = shell_exec($comd); 

//***** exec() also results in the same problem

文件仍在创建中,但 temp.txt 文件为空白。

发生了什么,如何获得所需的输出?

【问题讨论】:

    标签: php shell command-line


    【解决方案1】:

    根据我运行的几个测试,这与 gzip 压缩有关。在您的 CURL 请求中,您向服务器询问压缩版本,然后使用 brotli 解压缩。运行您原来的 curl 代码会在压缩时出现错误,例如 curl: (61) Unrecognized content encoding type. libcurl understands deflate, gzip content encodings.

    我的建议是删除所有压缩信息,删除brotli,然后使用简单的json。见下文:

    $comd = <<<EOT
    cd "/Users/user/Documents/RU_general"; curl 'https://api.perlego.com/metadata/v2/metadata/books/toc/682348' \
    -XGET \
    -H 'Origin: https://www.perlego.com' \
    -H 'Host: api.perlego.com' \
    -H 'Accept: application/json' \
    -H 'Connection: keep-alive' \
    -H 'Accept-Language: en-sg' \
    -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.1.2 Safari/605.1.15' \
    -H 'Referer: https://www.perlego.com/book/682348/10-human-how-your-bodys-microbes-hold-the-key-to-health-and-happiness-pdf' > temp1.txt
    EOT;
    

    接下来,我建议您使用 PHP Curl 实现,而不是使用 shell_exec。并非所有托管都允许shell_exec,并且如果托管系统不提供curl,或者在您的情况下甚至brotli,这在Linux服务器中不是标准的,您也会被阻止。使用 PHP Curl 可以让您留在 PHP 中并确保您的代码是可移植的。

    【讨论】:

      猜你喜欢
      • 2017-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-01
      • 1970-01-01
      • 2012-09-05
      • 2018-05-26
      • 1970-01-01
      相关资源
      最近更新 更多