【问题标题】:How does variable assignment in an expression work?表达式中的变量赋值如何工作?
【发布时间】:2011-11-05 03:06:37
【问题描述】:

这是我以前见过的一种做法,但不是很常见:一个变量在值本身被评估的同时被分配给一个值(或者它是被评估的表达式本身?)。示例:

// Outputs "The value is 1"
$value = 1;
if ($var = $value) {
    echo "The value is $var";
}

好像是一样的:

$value = 1;
$var = $value;
if ($var) {
    echo "The value is $var";
}

另一个例子:

// Outputs "The value is 1"
$value = 1;
echo "The value is ".$var = $value;

我一直在使用它来缩短我的代码,主要是第一个示例:用于评估第一个变量或表达式,同时将其分配给同一表达式中的另一个。像这样的:

if ($status = User::save($data)) {
    echo "User saved.";
}
// do something else with $status

这似乎很基本,但我实际上找不到任何documentation,也许我不知道该去哪里找。看了这么多年才知道它是怎么工作的,我真的很喜欢使用它,但我不想随意使用它。

它使代码更短,对某些人来说可能不是很清楚,但绝对不会重复。这种方法有什么注意事项吗?这是完全安全的还是在任何情况下它可能会失败或导致意外行为?这似乎不是一种很常见的做法,所以我希望在我开始“发疯”之前找到一个解释。如果 记录在案,我们将非常感谢您提供指向正确页面的链接。

【问题讨论】:

    标签: php variables expression variable-assignment


    【解决方案1】:

    来自http://uk3.php.net/manual/en/language.expressions.php

    与许多其他语言一样,PHP 使表达式更进一步。 PHP 是一种面向表达式的语言,几乎所有东西都是表达式。考虑我们已经处理过的示例$a = 5。很容易看出这里涉及到两个值,整数常量5 的值和$a 的值,它也被更新为5。但事实是这里涉及到一个额外的价值,那就是赋值本身的价值。赋值本身的计算结果为分配的值,在本例中为 5。在实践中,这意味着 $a = 5,无论它做什么,都是一个值为 5 的表达式。因此,写像 $b = ($a = 5) 这样的东西就像写 @ 987654328@(分号表示语句的结束)。由于赋值是按从右到左的顺序解析的,所以你也可以写$b = $a = 5

    很多人会争辩说您不应该经常使用这种行为。例如,区分:

    if ($a == 5) { ... }
    

    if ($a = 5) { ... }
    

    很棘手!上面两种常用的惯用写法来区分它们:

    if (5 == $a) { ... }
    if (($a = 5)) { ... }
    

    第一个称为yoda condition,如果省略等于字符,则会导致语法错误。后者在运行时不会有任何不同,但是当表达式没有多余的括号时,一些代码检查器会输出警告。

    【讨论】:

    • “这里涉及到一个额外的值,那就是赋值本身的值”——这就是我遗漏的部分。
    【解决方案2】:

    http://php.net/manual/en/language.operators.precedence.php 是您可能需要的。

    依次计算 PHP 表达式,按照从高到低的顺序。
    因此,首先我们对赋值进行评估,然后对其应用条件语句。还涉及一些type juggling 魔术,将返回值即时转换为布尔值

    这种方法有什么注意事项吗?

    当然。如果零是一个有效的返回值,你的代码可能会让你失败。一个常见的例子是 strpos() 函数:

    if ($pos = strpos("a","aaa"))...
    

    【讨论】:

    • 谢谢,看来如果使用得当,这是“可以”的。很抱歉写了这样一个“愚蠢”的问题,但在实践中很少见。我得到了关于评估为“假”的部分,例如 int(0)string('0'),必须根据具体情况考虑。
    • @Wesley 实际上没有什么愚蠢的,通常的 SO 问题要愚蠢得多。这确实是不寻常的行为,但对于 PHP 编码人员来说却如此熟悉,以至于难以解释。还有许多值被计为 FALSE - 空字符串、NULL、空数组。
    • 这确实是表达式$a = $b; 实际上返回我缺少的$b 的值的部分。例如,我从来不知道$a = $b = $c; 会起作用,更不用说返回值了。
    • 我只是不习惯被否决,我立即得了一分,现在一切都结束了,这似乎很清楚。欢迎回来 - 我错过了你的粗鲁评论:)
    • @Wesley LOL 我现在看到了。嗯,不是我。我不知道谁能拒绝这样一个经过深思熟虑、措辞恰当的问题,要求链接到文档
    【解决方案3】:

    赋值的结果是右手表达式的结果,所以$var = $value 的计算结果为$value。现在,您必须考虑 PHP 中 FALSETRUE 的确切含义。

    来自documentation

    FALSE:
     the boolean FALSE itself 
     the integer 0 (zero) 
     the float 0.0 (zero) 
     the empty string, and the string "0" 
     an array with zero elements 
     an object with zero member variables (PHP 4 only) 
     the special type NULL (including unset variables) 
     SimpleXML objects created from empty tags
    
    TRUE:
      everything not listed above
    

    如果赋值为TRUE,则 ifs 被命中。

    【讨论】:

    • 您的第一句话很好地说明了这一点。我得到了关于“虚假”的部分,现在测试似乎我们可以使用$a = 2; if (($b = $a) === 2){echo $b;}我从来不知道。谢谢,很抱歉给 SO 带来了另一个基本问题——这种情况很少见。
    【解决方案4】:

    表达式中的变量赋值如何工作?

    很明显,也许太明显了,所以我说:总是一样。表达式是expressionDocs

    让我们把它分开:

    if ($var = $value)
    
    [1] := if ([2])
    [2] := $var = $value
    
    1. 是一个 if 表达式。这是 [2] 的布尔值。
    2. 是一个变量赋值表达式。结果为$value

    因此,一个常见的错误是写

    if ($a = $b)
    

    当它打算写作时

    if ($a == $b)
    

    可能在打字时发生。

    在 PHP 中,基本上“任何有值的东西”都是一个表达式。

    【讨论】:

    • 如果它是一个表达式,那么你可以写成$b = if ($var = $value)。此外,文档没有这样描述它。
    • 我认为你被表达式必须“返回”某些东西的期望误导了。使用if,您可以表示以下状态/块有条件进一步表示。至于文档,请查看页面顶部附近给出的函数示例(第一个示例),您可以在答案中找到链接。在 PHP 中,几乎所有的东西都是一个表达式。也应该在该页面上。
    • 这就是“表达”的意思;它是一个评估值的东西(这正是链接中第一段所说的)。 if 是“控制结构”或“复合语句”。
    • 尽管有语义(表达式/语句),但这很好地阐明了它,谢谢 hakre。我猜 [2] 返回值是我觉得奇怪的部分。
    • 也许我对术语表达式在脚本语言中的含义有更广泛的看法。根据手册,您是对的,它最准确地描述为“任何有价值的东西”。编辑答案以更好地反映这一点。 if 表达式确实在括号内注明,不包括 if
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-21
    • 1970-01-01
    • 2017-04-07
    • 2014-12-30
    • 2010-10-05
    • 2021-06-18
    相关资源
    最近更新 更多