Когда Eval зло в PHP? - PullRequest
       121

Когда Eval зло в PHP?

82 голосов
/ 04 июня 2009

За все годы, что я разрабатывал в php, я всегда слышал, что использование eval() - это зло.

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

// $type is the result of an SQL statement
// e.g. SHOW COLUMNS FROM a_table LIKE 'a_column';
// hence you can be pretty sure about the consistency
// of your string
$type = "enum('a','b','c')";

// possibility one
$type_1 = preg_replace('#^enum\s*\(\s*\'|\'\s*\)\s*$#', '', $type);
$result = preg_split('#\'\s*,\s*\'#', $type_1);

// possibility two
eval('$result = '.preg_replace('#^enum#','array', $type).';');

Ответы [ 18 ]

3 голосов
/ 05 июня 2009

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

3 голосов
/ 04 июня 2009

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

2 голосов
/ 26 мая 2011

Плохое программирование делает eval () злом, а не функцию. Я использую его иногда, так как не могу обойти это в динамическом программировании на нескольких сайтах. Я не могу анализировать PHP на одном сайте, так как я не получу то, что хочу. Я бы просто получил результат! Я счастлив, что функция eval () существует, так как она делает мою жизнь намного проще. User-вход? Только плохие программисты подключаются к хакерам. Я не беспокоюсь об этом.

Я предсказываю, что у тебя скоро будут серьезные проблемы ...

Честно говоря, абсолютно бесполезно использовать непомерные функции, такие как eval, в интерпретируемом языке, таком как PHP. Я никогда не видел, чтобы eval выполнял программные функции, которые не могли бы быть выполнены другими, более безопасными способами ...

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

Я видел специально созданные примеры злоупотребления функцией eval, которая превзошла мое творчество. С точки зрения безопасности избегайте любой ценой, и я бы даже пошел так далеко, что потребовал бы, чтобы это было как минимум вариант в конфигурации PHP, а не «дано».

2 голосов
/ 27 февраля 2011

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

2 голосов
/ 14 января 2010

Другая причина, по которой eval является злом, заключается в том, что он не может быть кэширован кэшем байт-кода PHP, таким как eAccelertor или ACP.

1 голос
/ 02 апреля 2015

Вот решение для запуска PHP-кода, извлеченного из базы данных, без использования eval. Разрешает для всех в области функций и исключений:

$rowId=1;  //database row id
$code="echo 'hello'; echo '\nThis is a test\n'; echo date(\"Y-m-d\");"; //php code pulled from database

$func="func{$rowId}";

file_put_contents('/tmp/tempFunction.php',"<?php\nfunction $func() {\n global \$rowId;\n$code\n}\n".chr(63).">");

include '/tmp/tempFunction.php';
call_user_func($func);
unlink ('/tmp/tempFunction.php');

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

1 голос
/ 14 января 2010

Я часто использовал eval (), но я обнаружил, что в большинстве случаев вам не нужно использовать eval для выполнения трюков. Ну, у вас есть call_user_func () и call_user_func_array () в PHP. Это достаточно хорошо, чтобы статически и динамически вызывать любой метод.

Чтобы выполнить статический вызов, создайте свой обратный вызов в виде массива («имя_класса», «имя_метода») или даже в виде простой строки, такой как «имя_класса :: имя_метода». Для выполнения динамического вызова используйте обратный вызов в виде массива ($ object, 'method').

Единственное разумное использование для eval () - написать собственный компилятор. Я сделал один, но eval все еще злой, потому что его чертовски сложно отлаживать. Хуже всего то, что фатальная ошибка в уклоненном коде приводит к сбою кода, который его вызвал. Я использовал расширение Parsekit PECL, чтобы хотя бы проверить синтаксис, но все равно не радуюсь - попробуйте сослаться на неизвестный класс и произойдет сбой всего приложения.

0 голосов
/ 29 июня 2012

За исключением соображений безопасности, eval () не может быть скомпилирован, оптимизирован или кэширован с кодом операции, поэтому он всегда будет медленнее - намного медленнее - чем обычный код php. Таким образом, использование eval нецелесообразно, хотя это не делает его злым. (goto это зло, eval это только плохая практика / вонючий код / ​​безобразный)

...