为什么PHP在布尔上下文中将“ 0”视为FALSE?


12

作为包含一个字符的字符串,“ 0”在直观上并不是空的。与其他编程语言不同,为什么将PHP转换为布尔值后将其视为FALSE?


2
复制:stackoverflow.com/questions/523643/…。在PHP和javascript中都相同,请检查下面接受的答案。
Walfrat

5
这是因为PHP竭尽全力使其自身与所有其他编程语言都尽可能不一致。
大卫·阿诺

2
@DavidArno相反,它正在尽力保持一致;一旦开始自动广播字符串(一种非常方便的语言,该语言经常从URL或请求正文中获取var),则必须遵循该逻辑。如果'0'作为被处理0$x + 1,为什么不应该也被视为0,因此false,在if ( $x )
IMSOP

1
@DavidArno正好;)
linuxunil '16

1
@DavidArno一旦开始执行有损演员表转换,我认为有些矛盾是不可避免的。一致的解决方案包括拒绝某些类型的转换,并非常仔细地设计其余的类型。但是,很少有流行的语言是从头开始设计的。大多数是由意外流行的实验演变而成的,或者是由具有不同目的和包bag的较古老的语言演变而来的。即使是具有大量合理理论设计的C#,也具有C的一些遗产,而C从未像现在这样普遍。Snark就像“竭尽全力变得不一致”,就像在体育比赛中对裁判大喊大叫。
IMSoP '16

Answers:


12

PHP是为与Web请求一起使用而设计的(或者说是经过改进的),在Web请求中,您经常处理字符串输入(URL参数或来自浏览器中表单的POST请求)。这样,它将自动将字符串转换为其他类型。

一个简单的例子就是'1' + '2'给出3,而不是错误或'12'或其他解释。按照相同的逻辑,字符串'0'可以用作数字0

同时,与许多其他语言一样,PHP转换为布尔值时会将某些值视为“虚假”,就像您所说的那样,它们在直观上是“空”的。其中包括数字0,以及空字符串''和空数组[]。在一条if语句中,表达式显式转换为布尔值,因此if ( 0 )与相同if ( false )

将这两件事放在一起,您会遇到一个难题:一方面,正如您所说的'0'是一个非空字符串;另一方面,它是一个非空字符串。另一方面,我们说过它可以用作数字0,即“空”。PHP选择将“零度”比“严谨性”更重要,因此'0'被认为是“虚假的”。

简而言之:'0' == 0 == false; 要么(bool)'0' === (bool)(int)'0'


有人是否因为我敢于捍卫PHP并以廉价而无知的笑话来回答问题而否决了我的答案?还是我想指出的是我的答案有误或无益?
IMSoP '16

1
我认为PHP是从Perl获得的,Perl具有相同的“ "0" 错误”行为。在Perl中,字符串"0"和数字之间实际上没有任何可见的区别0-处理JSON时很烦人,但处理文本数据时却非常直观。这样就不可能使数字0为假,而字符串"0"也不为假。PHP和JavaScript借这个设计决定的,而是通过区分串/布尔变量/数字类型,同时还允许隐式转换添加一些混乱(PHP: ,0 == "0 foo"0 == false"0 foo" == true==没有传递的)
阿蒙

@amon是的,Perl采用了(几乎)所有运算符和内置函数将操作数强制为特定类型的有趣方法,并使用了额外的运算符,例如eq字符串相等性。但是,这并不能避免有损强制转换的非传递性:"0 foo"在布尔上下文中是真实的,但等于0under ==。因此if ( ! $foo ) ..$false = (1 == 2); if ( $foo == $false ) ... 不要给出相同的结果。我猜这门语言缺少一个“布尔等式”运算符,该运算符可以始终如一地对待它……
IMSoP 2016年

尽管当评估为数字时“ 0”为0,但是当我们在布尔上下文中(例如,在if语句中)使用字符串时,我们对其数字值不感兴趣。如果我们想将其解释为数字,则可以将其与某个数字进行比较,例如$_POST['id'] == 0,这可以清楚地表明我们希望将用户输入视为数字。
曾荫权

1
@MestreLion该示例是Perl而不是PHP。关键区别在于Perl中没有单独的布尔类型,因此$false最终设置为0;。因此,当您编写时$foo == $false,Perl不知道您想要布尔比较,而是将其强制转换为int。在PHP中,不会发生这种情况,因为$false布尔值为false,所以==将其强制转换为布尔值,结果与!
IMSoP'Sep

3

根据booleans上的PHP文档,它表示:

转换为布尔值时,以下值将被视为FALSE
...
空字符串和字符串“ 0”
...

除此以外:

其他所有值均视为TRUE(包括任何资源)。

如果您运行:

var_dump((bool) "0");

它将打印:

布尔值(false)

因此,它按预期工作。


要明确回答您的问题:

但是,在大多数情况下,强制转换是不必要的,因为如果操作员,函数或控制结构需要布尔参数,则值将自动转换。

这意味着PHP的“自动广播”会将“ 0”强制转换为整数0,这FALSE在诸如say if()语句这样的控制结构中也是如此。


我想知道将“ 0”转换为布尔值时将“ 0”视为FALSE的设计决策的原理,而不是需要显式强制转换。
曾荫权
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.