2016-09-21 82 views
2

本着看到Short-circuit evaluation like Python's "and" while storing results of checks的精神,我決定了解如何在PHP中最好地解決這個問題,但遇到了一個問題。在if()塊中分配多個變量時意外的行爲

意外

<?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" 

爲什麼以這種方式意外例如行爲?

+3

你確實意識到你正在分配而不是比較。 –

+0

@ Fred-ii- - 這不就是他們想要做的事情嗎? – Quentin

+0

@Quentin我....呃....猜*大聲笑*。我的錯。 –

回答

4

這是一個問題operator precedence。一個assignment expression returns the assigned value,所以你會得到前兩個操作AB。你得到布爾true相反,原因是&&操作符比賦值運算符的優先級高,所以在原始表達式

$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()) { 
2

布爾型&&的結果是bool! &&結合強於=。因此$b得到分配('B' && $c)這是一個bool ...與$a ...相同