对于我正在处理的复杂项目,我希望允许管理员使用布尔表达式为事件附加条件。
示例:
if (1 > 2 || (1 == 1 && 3 > 2)) [...]
以上将返回TRUE。
eval()
似乎是一个简单的解决方案,但我很清楚它带来的安全风险。 PHP是否提供了一种在不实际评估其他任意PHP代码的情况下评估上述表达式的方法?选项只能评估数学表达式,或者可能是接受函数白名单的eval()
清洁剂。
感谢您的帮助!
答案 0 :(得分:1)
最好的方法是使用token_get_all
作为你的建议“清洁剂”下面(不完整)代码段,以便您可以明白
function evalExpression ($expression)
{
$code = "return $expression;";
$token = token_get_all($code,TOKEN_PARSE);
# return
unset($token[1]);
foreach ($token as $key=>$value) {
if(is_array($value)) {
# white list token
$allow = [T_WHITESPACE,T_LNUMBER,/* add more token*/];
# remove white list token
if(in_array($value[0],$allow,true)) {
unset($token[$key]);
}
} else {
# white list string
$allow = [';','>'/* add more element*/];
# remove white list string
if(in_array($value,$allow,true)) {
unset($token[$key]);
}
}
}
# if token contain only white listed, $token should empty
if(!$token) {
return eval($code);
} else {
throw new \InvalidArgumentException('err');
}
};
# return bool
var_dump(evalExpression('2 > 1'));
# should error
var_dump(evalExpression('function(){}'));
由于eval构造很危险,因此在进入生产之前应该尝试使用恶意代码进行注入/测试