我有一些代码,看起来像这样。
eval('$ruleTrue = '."{$value} {$operator} {$value2};");我从数据库中提取大部分数值,并将它们与其他数值进行比较。运算符也来自数据库。可能的运算符是<、>、==。
当比较整型和浮点型时,这种方法非常有效。但在比较字符串时,它会断开。例如..
作品:5>4 $ruleTrue = true
不能正常工作: John-Adams == Alice $ruleTrue = true <-为什么?因为约翰对爱丽丝来说不是==。
由于某些原因,在比较字符串时,我的$ruleTrue变量被返回为true。
发布于 2012-12-21 05:46:42
您正在尝试评估以下代码:
$ruleTrue = John == Alice;John和Alice不是字符串,它们是未定义的常量。你想用引号把它们括起来。但是要小心,因为如果你的用户能够在你的数据库中编辑这些字段,他们可能会找到一种方法来取消对字符串的引用并执行他们自己的php代码,这可能是灾难性的。Eval以这种方式是非常不安全的,您可能不应该使用它。
发布于 2012-12-21 05:57:45
表达式John-Adams == Alice的解析方式有点像(John - Adams) == Alice。左边是试图减去两个字符串(未定义的常量被认为是‘无字’,等于它们名称的字符串;例如,John === 'John' ),为了理解这样一个奇怪的操作,PHP将这两个字符串转换为数字。作为整数,两个字符串的值都为0,因此左侧等于0。
一个整型。
现在,当PHP想要与==进行比较时,它想要将两端强制为同一类型。在本例中,它将转换为int。Alice也会转换为0。两边都是0,它们“明显”相等。
为了防止这种情况发生,你可能应该用引号将你的值括起来。您还可以考虑使用严格的等于运算符(===),除非您确实需要这种类型强制魔术。
或者,如果您有一组已知的运算符,您可以消除eval,并通过创建一个具有运算符的子函数的比较函数来使其更加安全和健壮。如下所示:
function compare($value1, $op, $value2) {
static $known_ops = array(
'==' => function($a, $b) { return $a == $b; },
'!=' => function($a, $b) { return $a != $b; },
...
# you can even make up your own operators. For example, Perl's 'eq':
'eq' => function($a, $b) { return "$a" === "$b"; }
...
);
$func = $known_ops[$op];
return $func($value1, $value2);
}
...
$ruleTrue = compare($value, $operator, $value2);现在你不必担心你的价值观了。您确实需要担心$operator,但是如果您让用户在没有验证的情况下输入它,那么这只是一个问题。在这种情况下,如果$op不在$known_ops中,您可能想抛出一个异常或其他东西,因为如果您让PHP来处理它,那么当它试图调用null时,您可能会得到一个致命错误。
发布于 2012-12-21 05:45:42
如果值是字符串,请确保用“引号”将它们括起来
https://stackoverflow.com/questions/13980954
复制相似问题