简体   繁体   English

在if()块中分配多个变量时出现意外行为

[英]Unexpected behavior when assigning multiple variables in if() block

In the spirit of seeing Short-circuit evaluation like Python's "and" while storing results of checks I decided to see how this could be best solved in PHP but I've run into an issue. 本着在存储检查结果的同时看到类似于Python的“和”之类的短路评估的精神,我决定看一下如何用PHP最好地解决此问题,但是我遇到了一个问题。

unexpected 意外

<?php
function check_a()
{
    return 'A';
}
function check_b()
{
    return 'B';
}
function check_c()
{
    return 'C';
}

if($a = check_a() && $b = check_b() && $c = check_c())
{
    var_dump($a);
    var_dump($b);
    var_dump($c);
}

Results in: 结果是:

bool(true)
bool(true)
string(1) "C"

code for what I wanted to happen 我想要发生的事情的代码

<?php
function check_a()
{
    return 'A';
}
function check_b()
{
    return 'B';
}
function check_c()
{
    return 'C';
}

// if(($a = check_a()) && ($b = check_b()) && $c = check_c()) // equivalent to line below
if(($a = check_a()) && ($b = check_b()) && ($c = check_c()))
{
    var_dump($a);
    var_dump($b);
    var_dump($c);
}

Results in: 结果是:

string(1) "A"
string(1) "B"
string(1) "C"

Why does the unexpected example act in this way? 为什么意外的例子如此行事?

This is a question of operator precedence . 这是运算符优先级的问题。 An assignment expression returns the assigned value , so you would expect to get A and B for the first two operations. 赋值表达式返回分配的值 ,因此您希望前两个操作获得AB The reason you're getting boolean true instead is that the && operator has a higher precedence than the assignment operator, so in the original expression 相反,您将布尔值设为true的原因是&&运算符的优先级高于赋值运算符,因此在原始表达式中

$a = check_a() && $b = check_b() && $c = check_c()

$a gets the value of check_a() && $b = check_b() && $c = check_c() , $a获得check_a() && $b = check_b() && $c = check_c()

$b gets the value of check_b() && $c = check_c() , $b获得check_b() && $c = check_c()

and $c gets the value of check_c() . $c获得check_c()的值。

The expressions check_a() && $b = check_b() && $c = check_c() , and check_b() && $c = check_c() return boolean true , because the use of the && operator causes the expressions to be evaluated as booleans, and all components of the expressions joined by && evaluate to true . 表达式check_a() && $b = check_b() && $c = check_c()check_b() && $c = check_c()返回布尔值true ,因为使用&&运算符会使表达式被评估为布尔值,并且&&连接的表达式的所有组成部分的计算结果均为true

To get the results you expect, you can add parentheses as you did, or you can use the and logical operator instead of && , because it has a lower precedence than the assignment operator. 要获得期望的结果,可以像添加括号一样, 或者可以使用and逻辑运算符代替&& ,因为它的优先级低于赋值运算符。

if($a = check_a() and $b = check_b() and $c = check_c()) {

The result of a boolean && is a bool! 布尔&&的结果是布尔值! && binds stronger than = . &&绑定比=更强。 Therefore $b gets assigned ('B' && $c) which is a bool... Same obviously with $a ... 因此, $b被分配了('B' && $c) ,这是一个布尔值...与$a显然相同...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM