PHP exec () vs system () vs passthru ()


312

Які відмінності?

Чи є конкретна ситуація чи причина для кожної функції? Якщо так, чи можете ви навести кілька прикладів таких ситуацій?

PHP.net говорить, що вони використовуються для виконання зовнішніх програм. див. посилання З наведених прикладів я не бачу явної різниці.

Якби я просто запустив скрипт (bash або python), яку функцію ви мені рекомендуєте використовувати?


16
Існує також proc_open()і те popen(), і інше, що дозволяє більш високий ступінь контролю над породженим процесом.
Крістіан

Відповіді:


195

Вони мають дещо інше призначення.

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

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


147
Іноді переносимість потрібно жертвувати функціональністю. Є деякі речі, які PHP просто не може зробити добре.
Френк Крук

30
@Kalium: чи можете ви детальніше розповісти про свою заяву? просто констатація деякої нечіткої процентної статистики мене не переконує. Я вважаю, що використання системних викликів для виконання скриптів є цілком чудовим, доки вся програма не залежить від однієї групи скриптів у задній частині.
кодуваннябезпеки

46
@Christian izkata@izein:~$ dir -bash: dir: command not found- FreeBSD
Izkata

5
@OZ_ Я прийшов до ситуації, коли мені довелося робити дуже дорогі обчислення. Для цього жоден модуль PHP не був доступний. Я написав власну програму C і викликаю її з passthru (). Іноді портативність може бути менш важливою, ніж інші речі. Залежить від проекту.
Паоло

9
Крім того , це помилка думати , що PHP є стерпним до тих пір , як ви уникнути exec, system, passthru. PHP-код залежить від середовища, в якому він працює, і багато помилок безпеки через те, що це не враховується. Ось короткий приклад: stackoverflow.com/questions/3003145 / ...
Pacerier

131

Як зроблено з http://php.net/ && Chipmunkninja :

Система () Функція

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

Exec () Функція

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

Для цього ідеально адаптована функція exec в PHP. Замість автоматичного скидання всього тексту, що генерується програмою, виконується у вихідний потік, це дає вам можливість помістити цей текст у масив, повернутий у другому параметрі до функції:

Shell_exec () Функція

Більшість програм, які ми виконували до цього часу, були більш-менш реальними програмами1. Однак середовище, в якому працюють користувачі Windows та Unix, насправді набагато багатше, ніж це. Користувачі Windows мають можливість використовувати програму Windows Command Prompt, cmd.exe Ця програма відома як командна оболонка.

PassThru () Функція

Одна із захоплюючих функцій, яку надає PHP, аналогічна тій, яку ми бачили досі, - це функція passthru. Ця функція, як і інші, виконує програму, про яку ви їй кажете. Однак він переходить до негайного надсилання вихідної інформації з цієї програми у вихідний потік, з яким PHP працює в даний час (тобто або HTTP у сценарії веб-сервера, або оболонка у версії PHP командного рядка).

Proc_open () Функція і POPEN () функція

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


6
швидкість виконання shell_exec швидша, ніж інші альтернативні.
Дінеш Саїні

29
Вам слід згадати, що ви скопіювали свою відповідь безпосередньо з ChipmunkNinja .
TachyonVortex

7
@TachyonVortex, на щастя, він скопіював відповідь дослівно, оскільки ChipmunkNinja вже не існує.
Phileo99

2
Копія цієї статті є у машині зворотного зв'язку
bagonyi

2
А що з popen та proc_open?
CMCDragonkai

103

Попередні відповіді здаються трохи заплутаними або неповними, тому ось таблиця відмінностей ...

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

Інші речі, про які слід пам’ятати:

  • Shell_exec () та оператор backticks роблять те саме.
  • Є також proc_open () та popen (), які дозволяють вам інтерактивно читати / записувати потоки за допомогою команди, що виконує.
  • Додайте "2> & 1" до командного рядка, якщо ви також хочете захопити / відобразити повідомлення про помилки.
  • Використовуйте escapepeshellcmd (), щоб уникнути аргументів команд, які можуть містити проблемні символи.
  • Якщо передати змінну $ output в exec () для збереження виводу, якщо $ output не порожній, він додасть до нього новий вихід. Тому вам може знадобитися спочатку зняти ($ output).

які з них можуть виконати файл php?
Джоні, чому

1
@johnywhy none per se - якщо ви прямо не посилаєтесь на php cli або подібне. Я припускаю, що ти хочеш includeі друзів
Хаген фон Ейтцен

21

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

  • exec виконує команду і передає висновок абоненту (або повертає його в необов'язковій змінній).

  • passthruподібна до exec()функції тим, що вона виконує команду. Цю функцію слід використовувати замість exec()або system()коли вихід з команди Unix - це двійкові дані, які потрібно передати безпосередньо назад у браузер.

  • system виконує зовнішню програму та відображає вихідний, але лише останній рядок.

Якщо вам потрібно виконати команду і передати всі дані команди безпосередньо назад без будь-яких втручань, скористайтеся passthru()функцією.


8

Якщо ви запускаєте свій скрипт PHP з командного рядка, passthru()має одну велику перевагу. Це дозволить вам виконувати сценарії / програми, такі як vim, dialogтощо, дозволяючи цим програмам керувати керуванням та повертатися до вашого сценарію лише тоді, коли вони виконані.

Якщо ви використовуєте system()або exec()виконуєте ці сценарії / програми, це просто не працюватиме.

Gotcha: З якоїсь причини ви не можете виконати lessз допомогою passthru()PHP.


1
Я не розумію, що ти кажеш. Ви можете виконувати програми як з CLI, так і з (F) CGI (а також mod_php). Можуть існувати обмеження, накладені системою, наприклад, selinux. Але добре налаштована система вимкне їх вибірково. Звичайно, спільний хост - це вже інша історія, але ви не пропонуєте спільного середовища і шанованим клієнтам, ні?
Крістіан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.