if条件范围内的变量

问题描述 投票:0回答:1

在这个社区里,关于这个争论并不多,所以我想放弃这个问题。

我有这样一段代码,用于验证 $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 validation if-statement block scoping
1个回答
1
投票

这段代码不是很可读,也不是很可维护。 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'));

2
投票

导致问题的是懒惰评估的顺序,而不是范围。如果你改变你的 &&and 在你的情况下,顺序将被颠倒,你的代码将运行正常。

基本上,您的 && 是优先于左边的,由于左边的赋值操作符,所以当右边被评估时,变量不存在。使用 and 将使左侧先计算,因为它的优先级比赋值运算符低,从而消除了这个问题。

作为一个旁白。你没有一个 if 语句。你所拥有的是一个三元表达式。

© www.soinside.com 2019 - 2024. All rights reserved.