it-swarm.com.ru

PHP exec () против system () против passthru ()

В чем различия?

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

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

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

297
codingbear

У них немного разные цели.

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

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

178
Kalium

Как взято из http://php.net/ && Chipmunkninja :

Функция system ()

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

Функция exec ()

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

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

Функция Shell_exec ()

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

Функция passthru ()

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

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

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

118
Dinesh Saini

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

+----------------+-----------------+----------------+----------------+
|    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.
  • "Код выхода" - это специальное значение, возвращаемое командой (также называемое "статусом возврата"). Ноль обычно означает, что он был успешным, а другие значения обычно являются кодами ошибок.

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

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

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

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

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

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

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

18
Cody Caughlan

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

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

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

6
Matt