在这个社区里,关于这个争论并不多,所以我想放弃这个问题。
我有这样一段代码,用于验证 $params['full_name']
:
$params = ["full_name"=>"John Doe"];
$full_name = $flag ? null : ( ( $tmp_name = trim(strip_tags((string)@$params['full_name']))
&& (strlen($tmp_name) > 3 && strlen($tmp_name) < 30)
) ? $tmp_name : out('The full name must be 3-30 characters', 'Invalid full name'));
尽管有 $params['full_name"]
被正确填充,我得到一个运行时错误。
<b>Notice</b>: Undefined variable: tmp_name
为什么会这样?难道我只是错过了关于在 if
语句?
这段代码不是很可读,也不是很可维护。 PHP 7 有 IFFY,所以我建议用这种方式重写。
$full_name = $flag
? null
: (function($params) {
$tmp_name = trim(strip_tags((string)@$params['full_name']));
return (strlen($tmp_name) > 3 and strlen($tmp_name) < 30)
? $tmp_name
: out('The full name must be 3-30 characters', 'Invalid full name');
})($params);
你的代码是可以工作的。 问题是操作的优先性。 这个 &&
操作符比赋值操作符具有更高的优先级,因此在这种情况下,对$tmp_name的赋值不会在逻辑的 &&
. 这一点体现在 操作图.
为了强制赋值首先发生,你必须用一组额外的parens来包裹赋值。
就个人而言,我不喜欢在没有必要的情况下绕过这样的问题,但既然你想要一个解释,这里有一个固定的版本。
$full_name = $flag ? null : ((($tmp_name = trim(strip_tags((string)@$params['full_name'])))
&& (strlen($tmp_name) > 3 && strlen($tmp_name) < 30))
? $tmp_name
: out('The full name must be 3-30 characters', 'Invalid full name'));
导致问题的是懒惰评估的顺序,而不是范围。如果你改变你的 &&
到 and
在你的情况下,顺序将被颠倒,你的代码将运行正常。
基本上,您的 &&
是优先于左边的,由于左边的赋值操作符,所以当右边被评估时,变量不存在。使用 and
将使左侧先计算,因为它的优先级比赋值运算符低,从而消除了这个问题。
作为一个旁白。你没有一个 if
语句。你所拥有的是一个三元表达式。