if 条件范围内的变量

Variables in if condition scope

这个社区关于这个争论的内容不多,所以我想放弃这个问题。

我有这段代码用于验证 $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 的赋值不会在计算逻辑 && 之前完成。 the operators chart.

中对此进行了说明

要强制首先发生赋值,您必须将赋值包含在一组额外的括号中。

就我个人而言,如果不是必须的话,我不喜欢围绕这样的问题编写代码,但由于您需要解释,这里有一个固定版本:

$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 语句。你得到的是一个三元表达式。