PHP中的Null、False和0有什么区别?

162

我被告知优秀的开发者可以识别并利用 NullFalse0 和其他好的 "空值" 实体之间的区别。在 PHP 中具体有什么区别?这与 === 有关吗?


事实上,几乎不可能真正弄清楚何时使用什么。我想当你使用 'null' 和 'false' 时保持一致是很重要的。当从方法中检索值时,我更喜欢使用 'null',因为我可以使用 'isset' 来确定是否返回了一个值,而不是使用 'empty',因为它不会考虑到:'false'、'0'、''0'' 或空字符串,这些在许多情况下都是可行值。对我来说,在混乱的结构中,这是最清晰的解决方案。 - JMRC
根据@gcb的评论 https://dev59.com/uXVC5IYBdhLWcg3w9GA9#ZZ-dEYcBWogLw_1bJFt7,三个等号会严格区分它们,而双等号则不会。默认情况下,请使用三个等号,除非您明确希望将0视为Null或false(或反之亦然)。 - Harps
18个回答

1
关于 PHP 中的 NULL,有一个有趣的事实:如果你将一个变量设置为 NULL,那么它就相当于调用了 unset()NULL 实际上意味着一个变量没有被赋值;false 是一个有效的布尔值,0 是一个有效的整数值,而 PHP 在 0"0"""false 之间有一些相当丑陋的转换。

1

我认为糟糕的开发者在他们的代码中找到了所有不同的null/0/false用法。

例如,开发人员最常犯的错误之一是以数据形式返回带有函数的错误代码。

// On error GetChar returns -1
int GetChar()

这是一个糖接口的示例。这在书籍“调试软件开发过程”和另一本书“编写正确代码”中有所解释。

问题在于对char类型进行的暗示或假设。在某些编译器上,char类型可以是非签名的。因此,即使您返回-1,编译器也可能返回1。这些类型的C++或C编译器假设很难发现。

相反,最好的方法是不要将错误代码与数据混合使用。因此,以下函数是最佳选择。

char GetChar()

现在变成了

// On success return 1
// on failure return 0
bool GetChar(int &char)

这意味着无论你的开发团队中有多年轻的开发人员,他们都不会犯这个错误。虽然这并不是在谈论代码中的冗余或依赖。

因此,总的来说,在语言中将bool作为第一类类型进行交换是可以的,我认为Joel在他最近的播客中谈到了这个问题。但是尽量不要在例程中混合使用布尔值和数据,那么你就应该完全没问题了。


0

Null 表示什么都没有,False 是一个位,而 0 可能是 32 位。

虽然我不是 PHP 专家,但在一些更现代的编程语言中,它们并不可互换。我有点想念 0 和 false 可以互换的时候,但布尔类型是一个实际的类型,你可以有与之相关联的方法和对象,所以这只是一个权衡。Null 就是 null,本质上是什么都没有。


0

嗯,我已经记不起来我的PHP时代有关"==="部分的答案了,但对于大多数C风格的语言,NULL应该在指针值的上下文中使用,false作为布尔值,而0则是数字值,例如int。 '\ 0'是字符上下文的惯用值。 我通常也更喜欢使用0.0表示浮点数和双精度。

所以... 快速的答案是:上下文。


0
在几乎所有现代语言中,null 逻辑上 指的是指针(或引用)没有值,或者变量未初始化。0 是零的整数值,false 是布尔值的假。让事情变得复杂的是,在 C 中,例如,null、0 和 false 都以完全相同的方式表示。我不知道 PHP 中是如何工作的。
然后,为了使事情更加复杂,数据库有一个 null 的概念,它意味着缺失或不适用,并且大多数语言没有直接的方法将 DBNull 映射到它们的 null。例如,直到最近,int 为 null 和 int 为零之间没有区别,但是随着可空 int 的出现,这种情况已经改变了。
很抱歉让这听起来很复杂。这只是因为这些年来,这一点一直是语言中的一个棘手问题,直到最近,它在任何地方都没有明确的解决方案。人们过去常常将事物凑合在一起,或者让空白或 0 代表数据库中的 null,但这并不总是有效。

0

False和0在概念上是相似的,即它们是同构的。0是自然数代数的初始值,而False是布尔代数的初始值。

换句话说,0可以被定义为当加到某个自然数时,得到相同数字的数字:

x + 0 = x

同样地,False 是这样一个值,使得它与任何其他值的析取结果都是该值本身:

x || False = x

Null在概念上完全不同。根据语言的不同,它们有不同的语义,但没有一个描述“初始值”像False和0一样。 Null没有代数。它涉及变量,通常用于表示变量在当前上下文中没有特定的值。在大多数语言中,没有定义Null的操作,使用Null作为操作数是错误的。在某些语言中,有一个称为“bottom”的特殊值,而不是“null”,它是计算值未终止的占位符。

我已经在其他地方更详细地讨论了NULL的影响。


1
离题了,false == 0 真的很愚蠢。特别是在 PHP 中,在函数中返回数据或失败时更是如此。看看 mysql_insert_id 的返回值:“成功时为上一个查询生成的 AUTO_INCREMENT 列的 ID,如果上一个查询未生成 AUTO_INCREMENT 值,则为 0,如果未建立 MySQL 连接,则为 FALSE。”基本上它可以返回 A)id、B)零、C)false……现在如果这是表中的第一项,id 将为零!所以三个值都是相同的!开发人员如何理解三种类型的零?……我也同意你关于 null 的帖子。 - gcb

0
有人能解释一下为什么在比较操作中 'NULL' 不仅仅是一个字符串吗?
$x = 0;
var_dump($x == 'NULL');  # TRUE   !!!WTF!!!

1
因为 PHP 内部将其转换为整数类型并进行比较。php > var_dump((int) "NULL"); // => int(0) php > var_dump((int) "BLA"); // => int(0) 请参阅 php.net/manual/en/language.operators.comparison.php 将字符串和资源转换为数字,进行常规数学运算。 - Sevyls

-1

关于 falsyness 的问题源自 PHP 的历史。该问题针对的是未定义良好的标量类型。

'*' == true -> true (string match)
'*' === true -> false (numberic match)

(int)'*' == true -> false
(string)'*' == true -> true

PHP7的严格性是一步向前,但可能还不够。https://web-techno.net/typing-with-php-7-what-you-shouldnt-do/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接