Отказ; Я полностью осведомлен о подводных камнях и "злах" eval, включая, но не ограничиваясь: проблемы производительности, безопасность, переносимость и т.д.
Проблема
Чтение руководства PHP по eval...
eval() возвращает NULL, если возврат не равен вызывается в оцененном коде, в котором в случае, если значение, переданное в вернулся. Если есть ошибка синтаксического анализа в оцененный код, eval() возвращает FALSE и выполнение следующих код продолжается нормально. Это не можно поймать ошибку синтаксического анализа в eval() с помощью set_error_handler().
Короче говоря, никакого захвата ошибки, кроме возвращаемого значения false, которое очень полезно, но я уверен, что я мог бы сделать лучше!
Причина
Часть функциональности сайта, над которой я работаю, полагается на выполнение выражений. Я бы хотел, чтобы я не проходил путь по песочнице или исполняющим модулям, поэтому я закончил использовать eval. Прежде чем вы начнете кричать: "Что, если клиент испортится?!" знайте, что клиент в значительной степени доверен; он не захочет ломать свой собственный сайт, и любой, кто получает доступ к этой функциональности, в значительной степени владеет сервером, независимо от eval.
Клиент знает о таких выражениях, как в Excel, и это не проблема, объясняющая небольшие различия, однако наличие некоторой формы предупреждения в значительной степени является стандартной функциональностью.
Это то, что у меня есть до сих пор:
define('CR',chr(13));
define('LF',chr(10));
function test($cond=''){
$cond=trim($cond);
if($cond=='')return 'Success (condition was empty).'; $result=false;
$cond='$result = '.str_replace(array(CR,LF),' ',$cond).';';
try {
$success=eval($cond);
if($success===false)return 'Error: could not run expression.';
return 'Success (condition return '.($result?'true':'false').').';
}catch(Exception $e){
return 'Error: exception '.get_class($e).', '.$e->getMessage().'.';
}
}
Примечания
- Функция возвращает строку сообщения в любом случае
- Выражение кода должно быть однострочным фрагментом PHP, без PHP-тегов и без конечной точки с запятой
- Новые строки преобразуются в пробелы
- Добавлена переменная, содержащая результат (выражение должно возвращать либо true, либо false, и для того, чтобы не конфликтировать с eval return, используется временная переменная.)
Итак, что бы вы добавили к дальнейшему помощнику пользователя? Существуют ли какие-либо дополнительные функции синтаксического анализа, которые могут лучше определить возможные ошибки/проблемы?
Крис.