В чем разница между методами passthru() и shell_exec() в PHP при выполнении системных команд?
В PHP существует несколько функций для выполнения системных команд: `exec()`, `system()`, `passthru()` и `shell_exec()`. Каждая из них имеет своё предназначение и поведение. Рассмотрим подробно отличия между `passthru()` и `shell_exec()`.
## shell_exec()
Функция `shell_exec()` выполняет команду через оболочку (shell) и **возвращает весь вывод в виде строки**. Это означает, что результат выполнения команды сохраняется в переменную PHP и может быть обработан программно.
php
$output = shell_exec(‘ls -la’);
echo $output;
Особенности:
— Возвращает `string` с полным выводом команды или `null` при ошибке.
— Вывод не отправляется напрямую браузеру — он буферизируется.
— Удобна, когда нужно обработать результат команды в PHP-коде.
— Является синонимом оператора обратных кавычек (« ` « ).
— Не предоставляет доступ к коду возврата команды.
## passthru()
Функция `passthru()` также выполняет команду через оболочку, но **передаёт вывод напрямую браузеру (или стандартный вывод)**, не буферизируя его. Это особенно полезно, когда команда возвращает бинарные данные.
php
passthru(‘convert image.png image.jpg’, $return_code);
echo «Код возврата: $return_code»;
Особенности:
— Вывод идёт непосредственно в браузер без промежуточного сохранения в переменную.
— Принимает второй необязательный параметр — переменную, в которую записывается **код возврата** команды.
— Оптимальна для передачи бинарных данных (изображения, архивы и т.д.).
— Не возвращает строку — возвращает `null`.
## Сравнительная таблица
| Характеристика | shell_exec() | passthru() |
|—|—|—|
| Возвращаемое значение | Строка с выводом | null |
| Вывод в браузер | Нет (буферизация) | Да (напрямую) |
| Код возврата | Недоступен | Доступен (2-й параметр) |
| Бинарные данные | Неудобно | Удобно |
| Буферизация | Да | Нет |
## Когда что использовать?
— **shell_exec()** — когда нужно получить текстовый вывод команды и обработать его в PHP (парсинг, сохранение в БД, логирование).
— **passthru()** — когда нужно передать бинарный вывод напрямую клиенту (например, результат работы ImageMagick) или когда важен код возврата команды.
## Важно о безопасности
Обе функции крайне опасны при использовании с пользовательскими данными без должной санитизации. Всегда применяйте `escapeshellarg()` или `escapeshellcmd()` для экранирования аргументов, чтобы предотвратить инъекцию команд (command injection).
