PHP eval и захват ошибок (насколько это возможно)
отказ; Я полностью осведомлен о подводных камнях и «бедах» eval, включая, помимо прочего: проблемы производительности, безопасности, переносимости и т. Д.
Эта проблема
Чтение руководства по PHP на eval ...
eval () возвращает NULL, если return не вызывается в вычисленном коде, и в этом случае возвращается значение, переданное в return. Если в обработанном коде есть ошибка разбора, 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, используется временная переменная.)Итак, что бы вы добавили для дальнейшей помощи пользователю? Существуют ли какие-либо дополнительные функции синтаксического анализа, которые могли бы лучше определить возможные ошибки / проблемы?
Крис.