该表达式的John-Adams == Alice
解析有点像(John - Adams) == Alice
. 左边试图减去两个字符串(未定义的常量被认为是'barewords',并且等于它们的名称的字符串化;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
。