Null vs.False vs.0在PHP中
有人告诉我,好的开发人员可以发现/利用"空","假"和" 0"以及其他所有"无"实体之间的差异。
有什么区别,特别是在PHP中?它和===
有关吗?
解决方案
这些值之间的差异始终归因于特定于语言的详细规则。我们为PHP学习的内容不一定适用于Python,Perl或者C等。虽然学习所用语言的规则很有价值,但过多地依赖它们却会带来麻烦。当下一个程序员需要维护代码并且我们使用了一些利用Null和False的小细节的构造时(例如),问题就来了。代码应该看起来正确(相反,错误的代码应该看起来错误)。
Null什么都不是,False是一位,0(可能)是32位。
不是PHP专家,但是在某些更现代的语言中,它们是不可互换的。我有点想念0和false可以互换,但由于boolean是实际类型,因此我们可以具有与之关联的方法和对象,所以这只是一个折衷。 Null是null,但是本质上没有任何东西。
False,Null,Nothing,0,Undefined等,等等。
这些中的每一个都具有与实际概念相关的特定含义。有时,多个含义会被重载为一个关键字或者值。
在C和C ++中," NULL"," False"和" 0"被重载为相同的值。
在Cthey're中,有3个不同的概念。
null或者NULL通常表示缺少值,但通常不指定原因。
" 0"表示自然数零,并且与1、2、3等具有类型等效性,并且在支持单独的" NULL"概念的语言中,仅应将其视为一个数字。
假表示不真实。它用于二进制值。它既不意味着未设置,也不意味着" 0"。它只是指示两个二进制值之一。
没有什么可以表明该值被专门设置为无,这表示与null相同,只是有目的。
在某些语言中,未定义表示尚未设置该值,因为没有代码指定实际值。
在数据库中使用Null表示"无记录"或者"无信息"。因此,我们可能有一个位域描述"此用户是否希望通过我们发送电子邮件",其中"真"表示他们愿意,"假"表示他们不希望发送任何东西,但是"空"表示我们不希望发送任何电子邮件不知道。它们可以通过外部联接等来实现。
在某些语言中,Null的逻辑含义通常是不同的。NULL不等于任何东西,因此if(a == NULL)始终为false。
因此,就我个人而言,我总是将布尔值初始化为FALSE,而将一个布尔值初始化为NULL看起来有点棘手(即使在C中,两者都只是0,这只是一个样式)。
好吧,我从PHP时代起就记不清回答" ==="部分了,但是对于大多数C风格的语言,应在指针值的上下文中使用NULL,将false用作布尔值,将零用作a值。数值,例如int。 '\ 0'是字符上下文的惯用值。我通常也更喜欢将0.0用于浮点数和双打。
所以..快速的答案是:上下文。
在PHP中,这取决于我们是否要验证类型:
( ( false !== 0 ) && ( false !== -1 ) && ( false == 0 ) && ( false == -1 ) && ( false !== null ) && ( false == null ) )
从技术上讲null是0x00
,但在PHP中是(null == 0x00)&&(null!== 0x00)
。
" 0"是整数值。
我认为糟糕的开发人员会在代码中找到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在最近的演讲中谈到了这一点。但是,请不要在例程中使用混合匹配布尔值与数据的方式,我们应该会很好。
在几乎所有现代语言中,null逻辑上指的是没有值或者未初始化的变量的指针(或者引用)。 0是零的整数值,而false是false的布尔值。为了使事情复杂,例如,在C中,null,0和false都以完全相同的方式表示。我不知道它如何在PHP中工作。
然后,使事情更加复杂的是,数据库具有null的概念,这意味着丢失或者不适用,并且大多数语言都没有直接的方法将DBNull映射为其null。例如,直到最近,int还是null还是零之间还没有区别,但是使用可为null的int进行了更改。
很抱歉,这听起来很复杂。只是多年来,这一直是语言的绊脚石,直到最近,还没有任何明确的解决方案。人们过去常常将所有内容放在一起或者将其设为空白或者0表示数据库中的空值,但这并不总是能很好地工作。
从PHP在线文档中:
" *要显式地将值转换为布尔值,请使用(bool)或者(boolean)强制类型转换。但是,在大多数情况下,强制类型转换是不必要的,因为如果运算符,函数或者控件结构需要布尔参数,则将自动转换值。
转换为布尔值时,以下值为FALSE:
*布尔值FALSE本身
*整数0(零)
*浮点数0.0(零)
*空字符串,字符串" 0"
*零元素数组
*成员变量为零的对象(仅PHP 4)
*特殊类型NULL(包括未设置的变量)
从空标签创建的SimpleXML对象
其他所有值都被视为TRUE(包括任何资源)。"
因此,在大多数情况下,都是相同的。
另一方面," ==="和" =="是不同的东西。通常,我们只需要"等于"运算符。澄清:
$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()相同。
NULL本质上意味着变量没有赋值。 false是有效的布尔值,0是有效的整数值,PHP在0," 0",""和false之间进行了相当难看的转换。
False和0在概念上相似,即它们是同构的。 0是自然数代数的初始值,而False是布尔代数的初始值。
换句话说,可以将0定义为一个数字,将其添加到某个自然数后,将得出相同的数字:
x + 0 = x
类似地,False是一个值,以使其与任何其他值的析取值都等于该值:
x || False = x
从概念上讲,Null是完全不同的东西。根据语言的不同,语义也有所不同,但是没有一个描述"初始值"为False和0。没有Null的代数。它与变量有关,通常表示变量在当前上下文中没有特定值。在大多数语言中,没有在Null上定义任何操作,并且将Null用作操作数是错误的。在某些语言中,有一个特殊的值称为"底部"而不是"空",它是不终止的计算值的占位符。
我已经在其他地方写了更多有关NULL含义的文章。
在PHP中,我们可以使用===和!==运算符不仅检查值是否相等,还检查它们的类型是否匹配。因此,例如:0 == false是true,而0 == false是false。 !=
和!==
也是一样。同样,如果我们使用提到的运算符将" null"与其他两个值进行比较,则可以预期得到类似的结果。
现在在PHP中,通常在返回一个有时可以为0(零)的值时使用这种值的质量,但有时可能是函数失败了。在PHP中,在这种情况下,我们将返回" false",并且我们必须使用身份运算符" ==="来检查这些情况。例如,如果我们要搜索一个字符串在另一个字符串中的位置,并且使用的是" strpos()",则此函数将返回数字位置,如果在字符串的最开始处找到该位置,则该数字位置可以为0,但如果根本找不到字符串,那么strpos()
将返回false
,并且在处理结果时必须考虑到这一点。
如果我们将在函数中使用相同的技术,那么熟悉标准PHP库的任何人都将了解正在发生的事情以及如何检查返回的值是所需的值还是在处理过程中发生了一些错误。实际上,函数参数也是如此,我们可以根据它们是数组还是字符串还是其他东西来不同地处理它们,并且该技术在PHP中也大量使用,因此每个人都可以很容易地获得它。所以我想这就是力量。
它是特定于语言的,但是在PHP中:
" Null"表示"无"。变量尚未初始化。
" False"的意思是"在布尔上下文中不是真的"。用于明确显示我们正在处理逻辑问题。
" 0"是一个" int"。与上面用于数学的其余部分无关。
现在,棘手的是,在像PHP这样的动态语言中,所有这些语言都在布尔上下文中有一个值(在PHP中为False)。
如果用==
进行测试,它就是在测试布尔值,因此我们将获得相等性。如果使用===
进行测试,它将测试类型,并且我们将得到不等式。
那么为什么它们有用呢?
好吧,看看strrpos()
函数。如果未找到任何内容,则返回False;如果未找到任何内容,则返回0!
<?php // pitfall : if (strrpos("Hello World", "Hello")) { // never exectuted } // smart move : if (strrpos("Hello World", "Hello") !== False) { // that works ! } ?>
当然,如果我们处理状态:
我们想在" DebugMode = False"(设置为off)," DebugMode = True"(设置为on)和" DebugMode = Null"(根本不设置,将导致硬调试;-)之间有所区别。
通常,编程语言倾向于具有真实和虚假的价值。什么是真话,什么是假话的规则因语言而异。
http://www.isolani.co.uk/blog/javascript/TruthyFalsyAndTypeCasting