Почему я не должен использовать Unix команды из PHP? - PullRequest
6 голосов
/ 22 февраля 2010

Почему вы предпочитаете не использовать команды bash через exec() в php?

Я не рассматриваю проблему переносимости (я определенно не буду портировать ее для запуска в Windows). Это просто вопрос хорошего способа написания сценариев.

С одной стороны:

  1. Мне нужно написать гораздо больше строк в php, чем в bash, чтобы выполнить ту же задачу. Например, когда мне нужно отфильтровать несколько строк в файле, я просто не могу создать образ, используя что-то вместо cat file | grep string > new_file. Это займет гораздо больше времени и усилий, чтобы сделать в php.
  2. Я не хочу анализировать все ситуации, когда что-то может пойти не так. Я просто покажу пользователю вывод команды bash, чтобы он знал, что именно произошло.
  3. Мне не нужно писать другую оболочку для функций файловой системы и использовать ее. Гораздо эффективнее использовать ОС для поиска файлов, манипулирования ими и т. Д.

С другой стороны:

  1. Вызов команды unix с exec() может быть неэффективным в большинстве случаев. Это довольно дорого, чтобы породить отдельный процесс. Речь не идет о скриптах, работающих под Apache, что даже намного менее эффективно, чем порождение из скриптов командной строки.
  2. Иногда это выглядит как «черная магия» и perl-подобные сценарии. Хотя этого можно избежать с помощью подробных комментариев.
  3. Может быть, я просто пытаюсь использовать два разных инструмента вместе, когда они не должны. Каждый инструмент имеет свое собственное приложение и не должен смешиваться вместе.
  4. Хотя я уверен, что пользователи не будут пытаться запускать сценарий в злонамеренных целях, использование exec() является потенциальной угрозой безопасности. В большинстве случаев пользовательские данные могут быть экранированы с помощью escapeshellarg(), но это все еще проблема, которую необходимо учитывать.

Ответы [ 11 ]

14 голосов
/ 22 февраля 2010

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

`rm -rf /`

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

это в основном религиозная вещь, большинство разработчиков пытаются написать код, который всегда работает. использование внешних команд - верный способ заставить ваш код не работать в некоторых системах (даже в одной и той же ОС).

10 голосов
/ 22 февраля 2010

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

Основная причина против использования exec () в PHP - это безопасность. Если вы доверяете своему пользователю дать команду exec () в bash, он может легко запускать вредоносные команды, такие как установка и запуск троянских программ, удаление файлов и т. П.

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

4 голосов
/ 22 февраля 2010

Даже если вы говорите, что переносимость не является проблемой, вы никогда не знаете наверняка, что нас ждет в будущем, поэтому я бы посоветовал вам пересмотреть эту позицию. Например, однажды меня попросили портировать редактор, написанный (кем-то еще), из Unix в DOS. Исходная программа не должна была быть портирована и была написана с конкретными вызовами Unix, глубоко встроенными в код. Изучив объем требуемой работы, мы отказались от этой задачи как отнимающей слишком много времени.

Я использовал вызовы exec в PHP; однако у меня не было другого способа выполнить то, что мне было нужно (мне пришлось называть другую программу, написанную на другом языке, без другого моста между языками). Однако, IMO, вызовы exec, которые не нужны, ужасны. Как уже говорили другие, они также могут создавать угрозы безопасности и замедлять вашу программу.

Как вы сказали сами, вам нужно хорошо документировать вызовы exec, чтобы быть уверенными, что они будут понятны программистам. Зачем создавать дополнительную работу? Не только сейчас, но и в будущем, когда любые изменения в вызове exec также необходимо будет документировать.

Наконец, я предлагаю вам немного лучше изучить PHP и его функции. Я не очень хорош с PHP, но всего за несколько минут с Google и php.net , я думаю, что достиг того же, что вы привели в качестве примера с:

$search_results = preg_grep($search_string, file($file_name));
foreach ($search_results as $result) {
    echo $result . "\n";
}

Да, это немного больше кода, но не так много, и вы можете поместить его в функцию, если это уместно ... и я не удивлюсь, если гуру PHP сможет его сократить.

3 голосов
/ 22 февраля 2010

ИМХО, основной проблемой при использовании exec () для выполнения * nix-команд через PHP является безопасность, больше, чем производительность или даже стиль кода.

Если у вас очень хорошая очистка входных данных (а это очень трудно сделать), вы можете не иметь никакой дыры в безопасности.

1 голос
/ 22 февраля 2010

Если вы стремитесь только к совместимости с Unix (что совершенно нормально), я не вижу в этом ничего плохого. Фактически серверная операционная система, доступная сегодня, является клоном Unix, за исключением, разумеется, Windows, которую я считаю в первую очередь нелепой в качестве серверной платформы (и, как я понимаю из опыта, это не просто ненависть Microsoft). Unix-совместимость - абсолютно законное требование на любом сервере, на мой взгляд.

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

EDIT: Да, а что касается проблемы безопасности, это просто вопрос того, чтобы убедиться, что вы полностью контролируете переменные, передаваемые операционной системе. Это проблема, которую вы должны учитывать при общении между процессами и языками, например, когда вы делаете запросы SQL. На мой взгляд, это не слишком большая причина, чтобы что-то не делать, это просто то, что нужно учитывать в этом случае, как и в любом случае.

1 голос
/ 22 февраля 2010

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

1 голос
/ 22 февраля 2010

PHP не является хорошим исполнителем. php порождает процесс из apache, и если этот процесс зависает, ваш сервер apache будет зависать, если ваш сайт также работает на том же apache; это не удастся.

Вы можете ожидать и глупых проблем, подобных этим, если это произойдет, вы даже не сможете перезапустить apache, не убив порожденный процесс вручную из оболочки.

http://bugs.php.net/bug.php?id=38915

поэтому, я не говорю о безопасности, запуск команд linux из php дает сбой больше, чем вы думаете, худшая часть использования exec, не всегда возможно вернуть сообщения об ошибках обратно в php. или напишите последующий метод, который зависит от того, что случилось с exec.

рассмотрим этот псевдо-пример:

exec ('bash myscript.sh',$x)
if (myScriptWasOk == true) then do this

Нет способа получить правильную переменную myScriptWasOk. Вы просто ничего об этом не знаете, иногда вам поможет $ x.

Все это, как говорится, если вам нужно что-то простое, и если вы проверили свой сценарий, и он работает нормально, просто сделайте это.

1 голос
/ 22 февраля 2010

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

1 голос
/ 22 февраля 2010

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

1 голос
/ 22 февраля 2010

Лично, если переносимость не является проблемой, я бы полностью использовал * nix-команды, такие как grep, locate и т. Д., Когда бы ни пытался дублировать эту функциональность в PHP.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...