如果陈述给出了错误的答案

时间:2011-01-04 16:54:38

标签: php

我长期在if if语句中使用赋值来简化事情。但在这种情况下,它没有按预期工作。这就是我所拥有的:

$Employee = GetEmployeeName($Record['employee_id']);
echo 'First name: '.$Employee['first_name'];
echo 'Last name: '.$Employee['last_name'];
echo 'Record first name: '.$Record['first_name'];
echo 'Record last name: '.$Record['last_name'];

echo 'Comparing first name: ';
var_dump(strcasecmp($Employee['first_name'], $Record['first_name']));

echo 'Comparing last name: ';
var_dump(strcasecmp($Employee['last_name'], $Record['last_name']));

echo 'Comparing both together: ';
var_dump(strcasecmp($Employee['first_name'], $Record['first_name']) 
         || strcasecmp($Employee['last_name'], $Record['last_name']));

echo 'All together now: ';
var_dump($Foo = GetEmployeeName($Record['employee_id']) 
         && (strcasecmp($Foo['first_name'], $Record['first_name']) 
             || strcasecmp($Foo['last_name'], $Record['last_name'])));

结果如下:

First name: ZACHARY
Last name: TAYLOR
Record first name: Zachary
Record last name: Taylor
Comparing first name: int(0)
Comparing last name: int(0)
Comparing both together: bool(false)
All together now: bool(true)

这没有任何意义。比较名字解析为0(假);比较姓氏解析为0(假);比较它们一起解析为假。然而,当我将赋值添加到if中时,它突然解析为真。我已经在ifs中长期分配变量了,我从未见过这种情况。奇怪的是,如果我在if之外分配,它可以正常工作。所以我可以做到这一点,但在这一点上,这是关于找出问题的原则,这样我就可以提高对语言的了解。

在这种情况下的分配给出了真实,正如你可以看到$ Employee被填充的事实。因此,最终的var_dump基本上是“真正的&& false”,应该解析为false。正确?

4 个答案:

答案 0 :(得分:4)

布尔运算符&&的赋值运算符=precedence。所以这个:

$Foo = GetEmployeeName($Record['employee_id']) 
     && (strcasecmp($Foo['first_name'], $Record['first_name']) 
         || strcasecmp($Foo['last_name'], $Record['last_name']))

相当于:

$Foo = (GetEmployeeName($Record['employee_id']) 
     && (strcasecmp($Foo['first_name'], $Record['first_name']) 
         || strcasecmp($Foo['last_name'], $Record['last_name'])))

将括号括在作业周围,它可以正常工作:

($Foo = GetEmployeeName($Record['employee_id'])) 
     && (strcasecmp($Foo['first_name'], $Record['first_name']) 
         || strcasecmp($Foo['last_name'], $Record['last_name']))

答案 1 :(得分:1)

我刚刚花了一个公平的时间来解决这个问题,并最终解决了这个问题。

我的测试代码:

var_dump($Foo = array('first_name' => 'ZACHARY', 'last_name' => 'TAYLOR') 
     && (strcasecmp($Foo['first_name'], 'Zachary') 
         || strcasecmp($Foo['last_name'], 'Taylor')));

给出输出:

PHP Notice:  Undefined variable: Foo in /home/sam/test.php on line 6
PHP Stack trace:
PHP   1. {main}() /home/lday/test.php:0
bool(true)

问题是$Foo仅在所有 =运算符右侧的操作发生后分配。因此,当您致电strcasecmp($Foo['first_name'], 'Zachary')时,您实际上正在执行strcasecmp('', 'Zachary'),其评估为-7(布尔true)。所以你的代码评估如下:

$Foo = true && (-7 || -7);

这显然是正确的。

如其他地方所示,解决方案是将$Foo放在括号中,因此首先对其进行评估:

var_dump(($Foo = array('first_name' => 'ZACHARY', 'last_name' => 'TAYLOR'))  
     && (strcasecmp($Foo['first_name'], 'Zachary') 
         || strcasecmp($Foo['last_name'], 'Taylor')));

答案 2 :(得分:0)

由于operator precedence,您的代码解释如下:

首先,结果:

GetEmployeeName($Record['employee_id']) && (strcasecmp($Foo['first_name'],
$Record['first_name']) || strcasecmp($Foo['last_name'],
$Record['last_name']))

如果选中

在此之后,结果是$Foo的asignet - 而if只检查此作业是否成功。

要避免这种情况,请使用大括号将camparision的各个部分正确分组。

答案 3 :(得分:-1)

strcasecmp

  

返回<如果str1小于str2,则为0; >如果str1大于str2则为0,如果它们相等则为0。

所以零的回报意味着他们彼此相等而不是假的

//这是PHP网站本身的示例代码

<?php
   $var1 = "Hello";
   $var2 = "hello";
   if (strcasecmp($var1, $var2) == 0) {
      echo '$var1 is equal to $var2 in a case-insensitive string comparison';
   }
?>

正如您在上面的评论中所述,这些都应该返回相同的结果。请执行示例代码,您将看到它们没有。

<?php

if(strcasecmp("ZACHARY", "Zachary") == 0) {
    echo "We have a match with a zero (int) return\n"; // this returns 0
}

echo !strcasecmp("ZACHARY", "Zachary")."\n"; // this will return 1

?>

如何使用var_dump比较int(0)返回将返回bool(false)

// returns int(0)
var_dump(strcasecmp("ZACHARY", "Zachary")); 

// will return bool(false) as it's comparing int(0) || int(0)
var_dump((strcasecmp("ZACHARY", "Zachary")) || (strcasecmp("ZACHARY", "Zachary")));