2009-04-09 3 views
258

В чем отличия?PHP exec() vs system() vs passthru()

Есть ли конкретная ситуация или причина для каждой функции? Если да, можете ли вы привести некоторые примеры этих ситуаций?

PHP.net говорит, что они используются для выполнения внешних программ. see reference Из примеров, которые я вижу, я не вижу никакой очевидной разницы.

Если бы я просто запускал скрипт (bash или python), какую функцию вы рекомендуете мне использовать?

+12

Существует также 'proc_open()' и 'popen()', оба из которых позволяют более высокую степень контроля над порожденным процессом. – Christian

ответ

157

У них несколько разные цели.

  • exec() предназначено для вызова системной команды и, возможно, работы с выходом самостоятельно.
  • system() предназначен для выполнения системной команды и немедленного отображения вывода - предположительно текста.
  • passthru() предназначен для выполнения системной команды, из которой вы хотите получить необработанное возвращение - предположительно, что-то двоичное.

Независимо от того, я предлагаю вам не использовать ни один из них. Все они производят очень неуправляемый код.

+128

Иногда переносимость должна быть принесена в жертву за функциональность. Есть некоторые вещи, которые PHP просто не может преуспеть. –

+9

Предоставлено, но 95% времени, когда люди хотят использовать вызов оболочки, все причины ошибочны. – Kalium

+28

@Kalium: можете ли вы подробнее рассказать о своем заявлении? просто заявив, что некоторые неопределенные статистические данные не убеждают меня. Я считаю, что использование системных вызовов для выполнения сценариев полностью прекрасное, если все приложение не зависит от одной группы скриптов в фоновом режиме. – codingbear

17

На самом деле все сводится к тому, как вы хотите обрабатывать выходные данные, которые команда могла бы вернуть, и хотите ли вы, чтобы ваш PHP-скрипт дождался завершения программы callle.

  • exec выполняет команду и передает выходные данные вызывающего абонента (или возвращает его в необязательном переменной).

  • passthru аналогичен функции exec(), поскольку он выполняет команду. Эта функция должна использоваться вместо exec() или system(), когда вывод команды Unix представляет собой двоичные данные, которые необходимо передать непосредственно в браузер.

  • system выполняет внешнюю программу и отображает вывод, но только последнюю строку.

Если вам нужно выполнить команду и иметь все данные из команды передается обратно без каких-либо помех, используйте функцию passthru().

5

Если вы используете PHP-скрипт из командной строки, passthru() имеет одно большое преимущество. Он позволит вам выполнять сценарии/программы, такие как vim, dialog и т. Д., Позволяя этим программам управлять и возвращаться к вашему скрипту только тогда, когда они будут выполнены.

Если вы используете system() или exec() для выполнения этих сценариев/программ, это просто не сработает.

Gotcha: По какой-то причине вы не можете выполнить less с passthru() в PHP.

+1

Я не понимаю, что вы говорите. Вы можете выполнять программы как из CLI, так и (F) CGI (а также mod_php). Могут быть введенные в систему ограничения, такие как selinux. Но система настройки скважины будет выборочно отключена. Конечно, хост * shared * - это другая история, но вы не будете предлагать * совместно используемую среду для уважаемых клиентов, нет? – Christian

94

system() Функция Функция

Система в PHP принимает строковый аргумент, с помощью команды для выполнения, а также любые аргументы, которые вы хотите, переданных этой команде. Эта функция выполняет указанную команду и выгружает любой результирующий текст в выходной поток (либо выход HTTP в ситуации веб-сервера, либо консоль, если вы используете PHP в качестве инструмента командной строки). Возврат этой функции является последней строкой вывода из программы, если она выводит текст.

exec() Функция Функция

система является весьма полезным и мощным, но одна из самых больших проблем, с ним в том, что все в результате чего текст из программы идет непосредственно в выходной поток. Будут ситуации, когда вы можете отформатировать полученный текст и отобразить его каким-либо другим способом или вообще не отображать его.

Для этого функция exec в PHP отлично адаптирована. Вместо того, чтобы автоматически сбрасывать весь текст, сгенерированный программой выполняется в выходной поток, это дает возможность поместить этот текст в массив, возвращаемый в качестве второго параметра функции:

shell_exec() Функция

Большинство программ, которые мы выполняли до сих пор, были, более или менее, настоящими программами1. Однако среда, в которой работают пользователи Windows и Unix, на самом деле намного богаче. У пользователей Windows есть возможность использовать программу командной строки Windows, cmd.exe. Эта программа называется командной оболочкой.

passthru() Функция

Одна увлекательная функция, PHP предоставляет аналогичные тем, которые мы видели до сих пор является функцией PassThru. Эта функция, как и другие, выполняет программу, о которой вы рассказываете. Тем не менее, он затем немедленно отправляет исходный вывод из этой программы в выходной поток, с которым работает PHP в настоящее время (например, HTTP в сценарии веб-сервера или оболочка в версии командной строки PHP).

proc_open() Функции и popen() функции

proc_open() похож на POPEN(), но обеспечивает гораздо большую степень контроля над выполнением программы. cmd - это команда, выполняемая оболочкой. descriptorspec - это индексированный массив, в котором ключ представляет номер дескриптора, а значение представляет, как PHP передает этот дескриптор дочернему процессу. pipe будет настроен на индексированный массив указателей файлов, которые соответствуют концу PHP любых создаваемых трубок. Возвращаемое значение представляет собой ресурс, представляющий процесс; вы должны освободить его, используя proc_close(), когда вы закончите с ним.

Кредиты: http://php.net/ & & Chipmunkninja (Ссылка не упоминается, потому что он не работает, 404 ошибка)

+4

Скорость выполнения shell_exec быстрее, чем другая альтернатива. –

+21

Следует упомянуть, что вы скопировали свой ответ непосредственно из [ChipmunkNinja] (http://chipmunkninja.com/Program-Execution-in-PHP%3A-exec-m @). – TachyonVortex

+5

@TachyonVortex к счастью, он скопировал ответ дословно, потому что ChipmunkNinja больше не существует. – Phileo99

51

предыдущие ответили, казался, все будет немного запутанными или неполными, так вот таблица отличий. ..

+----------------+-----------------+----------------+----------------+ 
| Command  | Displays Output | Can Get Output | Gets Exit Code | 
+----------------+-----------------+----------------+----------------+ 
| system()  | Yes (as text) | Last line only | Yes   | 
| passthru()  | Yes (raw)  | No    | Yes   | 
| exec()   | No    | Yes (array) | Yes   | 
| shell_exec() | No    | Yes (string) | No    | 
| backticks (``) | No    | Yes (string) | No    | 
+----------------+-----------------+----------------+----------------+ 
  • «Отображает выход» означает, что потоки вывода в браузер (вывод или командной строки, если запущен из командной строки).
  • «Can Get Output» означает, что вы можете получить вывод команды и назначить ее переменной PHP.
  • «Код выхода» - это специальное значение, возвращаемое командой (также называемое «статусом возврата»). Ноль обычно означает, что он был успешным, а другие значения обычно являются кодами ошибок.

Других разные вещи, чтобы быть в курсе:

  • The shell_exec() и оператор кавычки делать то же самое.
  • Есть также proc_open() и popen(), которые позволяют вам интерактивно читать/записывать потоки с исполняемой командой.
  • Добавить "2> & 1" в командную строку, если вы также хотите отображать/отображать сообщения об ошибках.
  • Используйте escapeshellcmd(), чтобы избежать аргументов команды, которые могут содержать проблемные символы.
  • Если вы передаете переменную $ output в exec() для хранения вывода, если $ output не пуст, он добавит к нему новый вывод. Поэтому вам может потребоваться сначала отключить ($ output).