【发布时间】:2011-03-14 12:38:13
【问题描述】:
免责声明;我完全了解 eval 的陷阱和“邪恶”,包括但不限于:性能问题、安全性、可移植性等。
问题
阅读有关 eval 的 PHP 手册...
eval() 返回 NULL,除非 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 标记,也没有结束分号
- 新行转换为空格
- 添加了一个变量来包含结果(表达式应该返回真或假,为了不与 eval 的返回冲突,使用了一个临时变量。)
那么,您会添加什么来进一步帮助用户?是否有任何进一步的解析函数可以更好地查明可能的错误/问题?
克里斯。
【问题讨论】:
-
如果您可以就您将使用的“表达式”提供更多反馈,也许我们可以提供更多帮助。我可以想到一些不错的 token_get_all 东西来验证用户输入;)
-
普通 PHP 代码?我计划允许对 PHP 的完全访问,但定义函数和类可能除外,这不是必需的。
-
@Sz。话虽如此,我现在建议使用symfony/expression-language(它在 10 年不可用)。
标签: php exception parsing eval