PHP shell_exec с командой ведет себя не так, как при ее выполнении через терминал

#php #shell #command-line

Вопрос:

Когда я выполняю следующую команду на терминале 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 файл пуст.

Что происходит и как я могу получить нужный мне результат?

Ответ №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 и обеспечивать переносимость вашего кода.