有人告诉我,好的开发人员能够发现/利用 Null、 False和 0以及所有其他好的“无”实体之间的差异。 是有什么不同,特别是在 PHP 中? 它与 ===有什么关系吗?
Null
False
0
===
这些值之间的差异总是归结为特定于语言的详细规则。对于 Python、 Perl 或 C 等等,您从 PHP 中学到的东西并不一定是正确的。虽然学习你正在使用的语言的规则是有价值的,但过分依赖它们是自找麻烦。当下一个程序员需要维护您的代码时,麻烦就来了,您已经使用了一些结构,这些结构利用了 Null 与 False 的一些小细节(例如)。您的代码应该看起来正确(相反,错误的代码应该看起来是错误的)。
Null 是空值,False 是一位,0(可能)是32位。
不是 PHP 专家,但在一些更现代的语言中,这些是不可互换的。我有点怀念0和 false 是可互换的,但是布尔型是一个实际的类型,你可以有方法和对象与它相关联,所以这只是一个折衷。但是,Null 是 Null,即本质上没有任何内容。
False、 Null、 Nothing、0、 UnDefinition 等等。
其中每一个都有与实际概念相关的特定含义。有时候,多个含义被重载到单个关键字或值中。
在 C和 C + + 中,NULL、 False和 0被重载为相同的值。 在 C # 中,它们是三个不同的概念。
NULL
null或 NULL通常表示缺乏价值,但通常没有说明原因。 0表示自然数为零,与 一,二,三,等具有类型等价性,在支持单独的 NULL概念的语言中,应该只处理一个数字。
null
False 表示非真相。在 二进制值中使用。它不意味着未设置,也不意味着 0。它只表示两个二进制值中的一个。
没有任何东西可以表明该值被特别设置为没有,这表明同样的事情为空,但意图。
在某些语言中未定义表示该值尚未设置,因为没有代码指定实际值。
在数据库中使用 Null 表示“没有记录”或“没有信息”。所以你可能有一个比特字段来描述“这个用户想不想被我们发送电子邮件”,其中 True 意味着他们想,False 意味着他们不想被发送任何东西,但是 Null 意味着你不知道。它们可以通过外部连接处等等来到。
NULL 的逻辑含义通常是不同的——在某些语言中,NULL 不等于任何值,所以如果(a = = NULL)总是为 false。
所以个人而言,我总是将一个布尔值初始化为 FALSE,而将一个布尔值初始化为 NULL 看起来有点讨厌(即使在 C 语言中,两个布尔值都是0... ... 只是一种样式)。
好吧,我在 PHP 的时候记不太清楚“ = = =”这部分,但是对于大多数 C 风格的语言,NULL 应该在指针值的上下文中使用,false 作为布尔值,0作为整数这样的数值。“0”是字符上下文的惯用值。对于 float 和 double,我通常也喜欢使用0.0。
所以,快速回答是: 背景。
在 PHP 中,这取决于是否验证类型:
( ( false !== 0 ) && ( false !== -1 ) && ( false == 0 ) && ( false == -1 ) && ( false !== null ) && ( false == null ) )
技术上无效是 0x00,但在 PHP ( null == 0x00 ) && ( null !== 0x00 )。
0x00
( null == 0x00 ) && ( null !== 0x00 )
0是一个整数值。
我认为糟糕的开发人员会在代码中发现 null/0/false 的各种不同用法。
例如,开发人员最常犯的错误之一就是以函数的数据形式返回错误代码。
// On error GetChar returns -1 int GetChar()
这是一个糖接口的例子。这在《调试软件开发过程》一书和另一本《编写正确的代码》一书中都有解释。
这样做的问题在于对字符类型的暗示或假设。在某些编译器上,字符类型可以是无符号的。所以即使返回 -1,编译器也可以返回1。在 C + + 或 C 中,这种编译器假设很难被发现。
相反,最好的方法是不要将错误代码与数据混在一起。
char GetChar()
现在变成了
// On success return 1 // on failure return 0 bool GetChar(int &char)
这意味着无论开发人员在您的开发工作室中有多么年轻,他或她永远不会犯这个错误。尽管这并不是指代码中的冗余或依赖。
所以一般来说,交换 bool 作为语言中的第一类类型是可以的,我认为 Joel 在他最近的邮件中谈到了这一点。但是尽量不要在你的例程中使用混合和匹配的数据,你应该是完全没有问题的。
在几乎所有的现代语言中,null 逻辑上来说指没有值的指针(或引用) ,或者没有初始化的变量。0是0的整数值,false 是布尔值,好吧,false。为了使事情变得复杂,例如,在 C 中,null、0和 false 都以完全相同的方式表示。我不知道它在 PHP 中是如何工作的。
然后,更复杂的是,数据库有 null 的概念,这意味着缺少或不适用,大多数语言没有直接的方法将 DBNull 映射到它们的 null。例如,直到最近,int 为 null 和为0之间还没有区别,但是这种区别被可为 null 的 int 所改变。
抱歉让你觉得这很复杂。多年来,这一直是语言中的一个难点,直到最近,还没有任何明确的解决方案。人们过去常常只是把东西拼凑在一起,或者在数据库中使用空或0表示空值,这并不总是能很好地工作。
来自 PHP 在线文档:
若要显式地将值转换为布尔值,请使用(bool)或(boolean)强制转换。 但是,在大多数情况下,强制转换是不必要的,因为如果运算符、函数或控制结构需要布尔参数,则值将被自动转换。 当转换为布尔值时,下列值被认为是 FALSE:
FALSE
0.0
"0"
TRUE
所以,在大多数情况下,都是一样的。
另一方面,===和 ==不是一回事。通常,您只需要使用“ equals”运算符。澄清:
==
$a == $b //Equal. TRUE if $a is equal to $b. $a === $b //Identical. TRUE if $a is equal to $b, and they are of the same type.
有关更多信息,请查看 PHP 在线文档中的“ 比较运算符”页面。
希望这个能帮上忙。
关于在 PHP 中使用 NULL的一个有趣的事实是: 如果将一个 var 设置为 NULL,那么这与在其上调用 unset()是相同的。
unset()
NULL本质上意味着变量没有赋值; false是一个有效的布尔值,0是一个有效的整数值,PHP 在 0、 "0"、 ""和 false之间有一些相当丑陋的转换。
false
""
False 和0在概念上是相似的,即它们是同构的。0是自然数代数的初始值,False 是布尔代数的初始值。
换句话说,0可以被定义为一个数,当把它加到某个自然数上时,得到相同的数:
x + 0 = x
类似地,False 是这样一个值,它与任何其他值的分离都是同一个值:
x || False = x
Null 在概念上是完全不同的东西。根据不同的语言,它有不同的语义,但是它们都没有将“初始值”描述为 False 和0。Null 没有代数。它适用于变量,通常表示变量在当前上下文中没有特定的值。在大多数语言中,没有在 Null 上定义任何操作,并且使用 Null 作为操作数是一个错误。在某些语言中,有一个称为“ bottom”的特殊值,而不是“ null”,后者是计算值的占位符,不会终止。
关于 NULL 在其他地方的含义,我已经写了更多的文章。
在 PHP 中可以使用 = = 和!= = 运算符不仅检查值是否相等,而且检查它们的类型是否匹配。例如: 0 == false是 true,而 0 === false是 false。!=和 !==也是如此。另外,如果您使用上面提到的运算符将 null与其他两个运算符进行比较,预计也会得到类似的结果。
0 == false
true
0 === false
!=
!==
现在在 PHP 中,这种值的质量通常用于返回值时,有时可以是 0(零) ,但有时可能是函数失败。在这种情况下,在 PHP 中返回 false,并且必须使用标识符 ===检查这些情况。例如,如果你正在搜索一个字符串在另一个字符串中的位置,而你正在使用 strpos(),这个函数将返回数字位置,如果字符串在最开始被找到,它可以是0,但是如果字符串根本没有被找到,那么 strpos()将返回 false,在处理结果时你必须考虑到这一点。
strpos()
如果你在你的函数中使用相同的技术,任何熟悉这个 PHP标准库的人都会明白发生了什么,以及如何检查返回的值是否是你想要的,或者在处理过程中是否发生了错误。函数参数也是如此,你可以根据它们是数组还是字符串或者其他什么,对它们进行不同的处理,这种技术在 PHP 中也被广泛使用,所以每个人都很容易理解。所以我想这就是力量。
Null 表示“ 没什么”。 var 尚未初始化。
False 的意思是“ 在布尔上下文中不正确”。用于明确显示您正在处理逻辑问题。
0 是一个 int。和上面的其他部分没有关系,用于数学。
int
现在,棘手的是,在 PHP 等动态语言中,它们在布尔上下文中都有一个值(在 PHP 中)是 False。
如果您使用 ==测试它,它将测试布尔值,因此您将得到相等的结果。如果您用 ===测试它,它将测试类型,您将得到不等式。
看看 strrpos()函数。如果没有找到任何值,返回 False; 如果在字符串的开头找到了值,返回0!
strrpos()
<?php // pitfall : if (strrpos("Hello World", "Hello")) { // never exectuted } // smart move : if (strrpos("Hello World", "Hello") !== False) { // that works ! } ?>
当然,如果你和国家打交道:
你想在 DebugMode = False(设置为关闭)、 DebugMode = True(设置为打开)和 DebugMode = Null(完全不设置,将导致难以调试; ——)之间做出区别。
DebugMode = False
DebugMode = True
DebugMode = Null
null是 null。 false是 false。悲哀但真实。
PHP 没有太多的一致性(尽管它在最新版本的基础上有所改进,但有太多的向下兼容)。尽管设计希望有一些一致性(在这里选择的答案中概述) ,但是当您考虑以不那么容易推理的方式使用 false/null的方法返回时,一切都变得令人困惑。
当它们已经对某些内容使用 false 时,经常会看到使用 null。例如 filter _ input ()。如果变量使过滤器失败,则返回 false; 如果变量不存在,则返回 null (不存在意味着过滤器也失败了吗?)
当作者关心失败的类型时,可以交换返回 false/null/string/etc 的方法是一种技巧,例如,如果您关心验证失败的原因,那么使用 filter_input()可以检查 ===false或 ===null。但是,如果您不这样做,那可能是一个陷阱,因为如果他们只记得为 ===false编写测试用例,那么他们可能会忘记为 ===null添加检查。而且大多数 php 单元测试/覆盖工具不会引起您对缺失的、未测试的代码路径的注意!
filter_input()
===false
===null
最后,这里有一些有趣的类型杂耍。甚至不包括数组或对象。
var_dump( 0<0 ); #bool(false) var_dump( 1<0 ); #bool(false) var_dump( -1<0 ); #bool(true) var_dump( false<0 ); #bool(false) var_dump( null<0 ); #bool(false) var_dump( ''<0 ); #bool(false) var_dump( 'a'<0 ); #bool(false) echo "\n"; var_dump( !0 ); #bool(true) var_dump( !1 ); #bool(false) var_dump( !-1 ); #bool(false) var_dump( !false ); #bool(true) var_dump( !null ); #bool(true) var_dump( !'' ); #bool(true) var_dump( !'a' ); #bool(false) echo "\n"; var_dump( false == 0 ); #bool(true) var_dump( false == 1 ); #bool(false) var_dump( false == -1 ); #bool(false) var_dump( false == false ); #bool(true) var_dump( false == null ); #bool(true) var_dump( false == '' ); #bool(true) var_dump( false == 'a' ); #bool(false) echo "\n"; var_dump( null == 0 ); #bool(true) var_dump( null == 1 ); #bool(false) var_dump( null == -1 ); #bool(false) var_dump( null == false ); #bool(true) var_dump( null == null ); #bool(true) var_dump( null == '' ); #bool(true) var_dump( null == 'a' ); #bool(false) echo "\n"; $a=0; var_dump( empty($a) ); #bool(true) $a=1; var_dump( empty($a) ); #bool(false) $a=-1; var_dump( empty($a) ); #bool(false) $a=false; var_dump( empty($a) ); #bool(true) $a=null; var_dump( empty($a) ); #bool(true) $a=''; var_dump( empty($a) ); #bool(true) $a='a'; var_dump( empty($a)); # bool(false) echo "\n"; #new block suggested by @thehpi var_dump( null < -1 ); #bool(true) var_dump( null < 0 ); #bool(false) var_dump( null < 1 ); #bool(true) var_dump( -1 > true ); #bool(false) var_dump( 0 > true ); #bool(false) var_dump( 1 > true ); #bool(true) var_dump( -1 > false ); #bool(true) var_dump( 0 > false ); #bool(false) var_dump( 1 > true ); #bool(true)
我刚刚浪费了1/2天试图得到一个 0,null,false返回从 strops!
strops
在我发现这个逻辑没有朝正确的方向发展之前,我一直在努力做的就是这些,看起来就像是 PHP 编码中的一个黑洞:
概念 使用一个托管在服务器上的域名,并确保它不是根级别的,好的,有几种不同的方法可以做到这一点,但是我选择了不同的,因为我已经完成了其他的 php 函数/构造。
不管怎么说,这就是计算的基础:
if (strpos($_SERVER ['SERVER_NAME'], dirBaseNAME ()) { do this } else { or that } { echo strpos(mydomain.co.uk, mydomain); if ( strpos(mydomain, xmas) == null ) { echo "\n1 is null"; } if ( (strpos(mydomain.co.uk, mydomain)) == 0 ) { echo "\n2 is 0"; } else { echo "\n2 Something is WRONG"; } if ( (mydomain.co.uk, mydomain)) != 0 ) { echo "\n3 is 0"; } else { echo "\n3 it is not 0"; } if ( (mydomain.co.uk, mydomain)) == null ) { echo "\n4 is null"; } else { echo "\n4 Something is WRONG"; } }
读完这篇文章后, 我发现这个有用! ! !
{ if ((mydomain.co.uk, mydomain)) !== false ) { echo "\n5 is True"; } else { echo "\n5 is False"; } }
感谢这篇文章,我现在明白了,即使它是圣诞节,它可能不是圣诞节作为 false,因为它也可以是一个 NULL的一天!
在浪费了一天时间调试一些简单的代码之后,真希望我以前就知道这个问题,因为我能够识别出问题,而不是到处去试图让它工作。它没有工作,因为 False,NULL和 0不都是一样的作为 True or False or NULL?
True or False or NULL
下面是一个例子:
Comparisons of $x with PHP functions Expression gettype() empty() is_null() isset() boolean : if($x) $x = ""; string TRUE FALSE TRUE FALSE $x = null; NULL TRUE TRUE FALSE FALSE var $x; NULL TRUE TRUE FALSE FALSE $x is undefined NULL TRUE TRUE FALSE FALSE $x = array(); array TRUE FALSE TRUE FALSE $x = false; boolean TRUE FALSE TRUE FALSE $x = true; boolean FALSE FALSE TRUE TRUE $x = 1; integer FALSE FALSE TRUE TRUE $x = 42; integer FALSE FALSE TRUE TRUE $x = 0; integer TRUE FALSE TRUE FALSE $x = -1; integer FALSE FALSE TRUE TRUE $x = "1"; string FALSE FALSE TRUE TRUE $x = "0"; string TRUE FALSE TRUE FALSE $x = "-1"; string FALSE FALSE TRUE TRUE $x = "php"; string FALSE FALSE TRUE TRUE $x = "true"; string FALSE FALSE TRUE TRUE $x = "false"; string FALSE FALSE TRUE TRUE
请参阅此文以获得更多关于 PHP 中 类型比较的参考资料。它应该会让您有一个清晰的理解。
虚假性的问题来自 PHP 的历史。问题的目标是定义不明确的标量类型。
'*' == true -> true (string match) '*' === true -> false (numberic match) (int)'*' == true -> false (string)'*' == true -> true
PHP7的严格性是一个进步,但也许还不够
有人能解释一下为什么‘ NULL’不仅仅是比较实例中的字符串吗?
$x = 0; var_dump($x == 'NULL'); # TRUE !!!WTF!!!