表达式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 时,您可能会遇到致命错误.