Intereting Posts
PHP Хранить ключевое значение из ассоциативного массива в простой массив Проблемы с отображением японских символов с использованием PHP и MySQL CakeEmail в cakephp 2 может отправлять электронную почту одному и тому же smtp, но не swiftmailer в laravel Как заменить <p> <br> </ p> на конец строки, которая содержит пробелы, разрывы строк и табуляции? Regex? PHP Mailer Вы должны указать хотя бы один адрес электронной почты Могу ли я сделать более одного запроса на связку? Как установить более старую версию PHPUnit через PEAR? Удаление элементов из массива, если они существуют в другом массиве Получить идентификатор элемента и установить его как переменную Каков алгоритм, лежащий в основе вложенных комментариев? Не удалось загрузить ресурс: прервана загрузка кадра – Agian Laravel redirect () -> route () не работает корректно (просмотр в старом состоянии никогда не обновляется) Как изменить поиск в WordPress, чтобы он запрашивал термины таксономии и термины категории? Установка значения текстовой области HTML-формы? установка композитора на общем хосте

exec (): цитирование полной команды в Windows

Я написал веб-приложение, которое использует exec () для запуска внешней программы. Путь к программе настраивается и, как ожидается, будет содержать пробелы в имени. Как мы все знаем, командная строка Windows принимает пробелы в именах файлов или параметрах, вам просто нужно их удвоить:

C:\>C:\Archivos de programa\GraphicsMagick-1.3.12-Q16\gm.exe "C:\Archivos" no se reconoce como un comando interno o externo, programa o archivo por lotes ejecutable. C:\>"C:\Archivos de programa\GraphicsMagick-1.3.12-Q16\gm.exe" GraphicsMagick 1.3.12 2010-03-08 Q16 http://www.GraphicsMagick.org/ 

Все идет нормально. Проблема, с которой я столкнулась, – это использование самой функции exec () PHP. На некоторых серверах Windows требуется заключить полную команду (параметры программы +) в двойные кавычки:

 exec('""C:\Archivos de programa\GraphicsMagick-1.3.12-Q16\gm.exe" version"'); 

… и другие серверы Windows требуют не использовать двойные кавычки:

 exec('"C:\Archivos de programa\GraphicsMagick-1.3.12-Q16\gm.exe" version'); 

Я могу прочитать константу PHP_OS чтобы определить, работает ли на сервере Windows, но я не знаю, каково правило за кавычками или не цитирует тему. Если это объясняется в руководстве PHP, я не могу его найти.

Можно ли программно определить, нужны ли кавычки, поэтому мне не нужно вручную настраивать каждый экземпляр приложения?

Обновление № 1: меня неправильно поняли, поэтому я переформулировал части вопроса, чтобы сделать его более понятным.

Обновление № 2: я нашел комментарий в руководстве по PHP, в котором объясняется точная причина, по которой необходимы дополнительные кавычки (PHP выдает внутренний вызов cmd /c ). Я до сих пор не знаю, почему это кажется истинным или ложным в зависимости от системы.

Я написал это быстрое и грязное обходное решение:

 <?php class Thumb{ const GM_PATH = 'C:\\Archivos de programa\\GraphicsMagick-1.3.12-Q16\\gm.exe'; /** * Quote full command if required by server (program + arguments) */ private static function quoteFullCommand($command){ // Test only once per script static $extra_quotes_required=NULL; if( is_null($extra_quotes_required) ){ if(PHP_OS=='WINNT'){ // This call will be correct (0) if and only if the server requires extra quotes exec('""sort" /?"', $output, $return); $extra_quotes_required = $return==0; }else{ $extra_quotes_required = FALSE; } } if($extra_quotes_required){ $command = '"' . $command . '"'; } return $command; } /** * Return output from "gm version" */ public static function graphicsMagickVersion(){ $command = escapeshellarg(self::GM_PATH) . ' version '; $command = self::quoteFullCommand($command); exec($command, $output, $return); return trim(implode(PHP_EOL, $output)); } } 

Однако было бы лучше предсказать это из версии PHP или серверной ОС, поэтому ссылки на документацию или дополнительные советы приветствуются.

Обновление: я просмотрел часть исходного кода PHP, которая заботится о запуске внешних команд в Windows:

http://svn.php.net/viewvc/php/php-src/trunk/TSRM/tsrm_win32.c

Следующая строка добавляет дополнительные команды к полной команде:

 sprintf(cmd, "%s /c \"%s\"", TWG(comspec), command); 

Согласно истории файлов, эта строка была впервые добавлена ​​29 мая 2008 года ( r260429 ):

MFH: Исправить ошибку при цитировании команды и указать параметры во время вызова exec, результатом является то, что cmd.exe / c разбивает первую и последнюю цитату.

Следующие версии PHP были 5.3.0 и 5.2.7, но строка находится в ветви 5_3, а не в 5_2. Я недостаточно знаком с процессом разработки PHP, поэтому я не могу найти журнал изменений или сказать, к каким точным версиям PHP исправлено исправление, но я бы осмелился сказать, что это была ошибка в PHP, и она была исправлена ​​на PHP /5.3.0 (но он не был обращен к 5.2, поэтому они не сломали устаревшие вещи).

Таким образом, мое обходное решение, вероятно, слишком велико. Вам просто нужно проверить PHP-версию и версию:

 if( PHP_OS=='WINNT' && version_compare(PHP_VERSION, '5.3.0', '<') ){ $command = $command = '"' . $command . '"'; }