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

时间:2016-09-21 15:22:35

标签: php variables

本着看Short-circuit evaluation like Python's "and" while storing results of checks的精神,我决定看看如何在PHP中最好地解决这个问题,但我遇到了一个问题。

意想不到

<?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);
}

结果:

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

我想要发生的代码

<?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);
}

结果:

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

为什么意外示例以这种方式行事?

2 个答案:

答案 0 :(得分:4)

这是operator precedence的问题。一个assignment expression returns the assigned value,因此您希望前两个操作获得Btrue。您获得布尔&&的原因是$a = check_a() && $b = check_b() && $c = check_c() 运算符的优先级高于赋值运算符,因此在原始表达式中

$a

check_a() && $b = check_b() && $c = check_c()获取$b

的值

check_b() && $c = check_c()获取$c

的值

check_c()获取check_a() && $b = check_b() && $c = check_c()的值。

表达式check_b() && $c = check_c()true返回布尔值&&,因为使用&&运算符会导致表达式被评估为布尔值,以及由true加入的表达式评估为and

要获得您期望的结果,您可以像添加括号那样添加括号,可以使用&&逻辑运算符而不是if($a = check_a() and $b = check_b() and $c = check_c()) { ,因为它具有较低的值优先于赋值运算符。

targetEntity="AppBundle\Entity\ProductInterface"

答案 1 :(得分:2)

布尔值&&的结果是布尔! &&=强大。$b。因此,('B' && $c)被分配$a这是一个布尔...明显与select convert(column1,'US7ASCII','WE8ISO8859P1') from table; ...