Php 给出错误答案的If语句

Php 给出错误答案的If语句,php,Php,我早就在长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

我早就在长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(false);比较姓氏解析为0(false);将它们比较在一起会被认为是错误的。然而,当我将赋值添加到if中时,它突然变成true。我在ifs中分配变量已经很长时间了,我从未见过这种情况发生。奇怪的是,如果我在if之外赋值,它就可以正常工作。所以我可以这样做,但在这一点上,这是关于找出问题所在的原则,这样我就可以提高我的语言知识


本例中的赋值为true,您可以通过填充$Employee这一事实看到这一点。因此,最终的
var_dump
本质上是“true&&false”,应该解析为false。对吗?

布尔运算符
&&
的值高于赋值运算符
=
。因此:

$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']))
由于以下原因,您的代码被解释为:

首先,结果是:

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

在这之后,结果被分配到
$Foo
-如果
只检查分配是否成功

为避免出现这种情况,请使用大括号正确地对营地的各个部分进行分组。

:

如果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';
   }
?>

我刚刚花了相当长的时间来解决这个问题,终于找到了问题所在

我的测试代码:

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')));

不,最终的
var\u dump()
仅转储
$Foo
的值。我怀疑这里出现了一些类型转换问题。请记住strcasecmp()不返回bool,而是一个int。您应该尝试类似于
(strcasecmp($Employee['first\u name'],$Record['first\u name'])==0)
,以便将strcasecmp()的输出转换为bool值,以便稍后进行进一步比较。我知道它会返回一个int,但当它们相等时,返回0,解析为false。:)不,他没有。:)测试
strcasecmp($Employee['first\u name'],$Record['first\u name'])==0
与测试
相同!strcasecmp($Employee['first\u name',$Record['first\u name'))
,但无需测试是否等于零。当用if包装时,它们都以相同的方式结束。@Andrew,当然
(int)0
相当于PHP中的
(bool)false
,而
(int)1
相当于
(bool)true
,但您应该检查其他整数。我不确定这是否适用。我现在找不到上面的文件。在任何情况下,您都应该明确定义您想要的内容。这会让你的生活更轻松。。。相信我,笨蛋的儿子。检查我的问题历史记录;我以前曾被操作符优先级妨碍过。但是,根据PHP文档,“虽然=的优先级低于大多数其他运算符,但PHP仍然允许类似以下表达式:if(!$a=foo()),在这种情况下,foo()的返回值被放入$a。”这有什么逻辑限制?它们没有详细说明什么表达式提升了class='s的优先级。@Gumbo我有点搞不懂为什么它的计算结果不是
$Foo=true&&(false | | false)
,它显然返回false。你能解释一下我在这里遗漏了什么吗?@lonesomeday:由于运算符优先级(
&
的优先级高于
=
,因此逻辑AND运算在赋值操作之前进行计算)表达式
$Foo=true&&(false | false)
相当于
$Foo=(true&(false | false))
。但是
$Foo=(true&&(false)| false))
->
$Foo=(true&&false)
->
$Foo=(false)
,那么为什么它会作为
true
转储呢?@Gumbo相当-返回
false
,0表示false。在这种情况下,Equal意味着false。但这不是我的问题所在。PHP文档声明零表示彼此相等,而不是错误,PHP文档还声明
(bool)0===false
。对。它返回
(int)0
。如果(0),我基本上会执行
,这是错误的。我不确定你没有得到这其中的哪一部分。所有这些都与我的问题无关,为什么最后一个语句与前面的语句不一致,这显然是由于运算符优先级而不是
strcasecmp
的返回值。您试图将返回int值作为布尔值进行比较,但为了准确起见,这不会给出您想要的结果,
和&
的优先级高于
=
,但
的优先级不高@lonesomeday:谢谢你的提示,我刚才看到了,并重新表述了我的答案;)啊哈!谢谢你找出了上面让我们困惑的地方。
$Foo = true && (-7 || -7);
var_dump(($Foo = array('first_name' => 'ZACHARY', 'last_name' => 'TAYLOR'))  
     && (strcasecmp($Foo['first_name'], 'Zachary') 
         || strcasecmp($Foo['last_name'], 'Taylor')));