有人告诉我,优秀的开发人员可以发现/利用所有其他优秀的“无”实体Null
之间False
的区别。
有什么区别,特别是在 PHP 中?有关系吗?0
===
18 回答
它是特定于语言的,但在 PHP 中:
Null
意思是“什么都没有”。var 尚未初始化。
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
(设置为关闭)、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
是否关心验证失败的原因。但是如果你不这样做,这可能是一个陷阱,因为===null
如果他们只记得为===false
. 而且大多数 php 单元测试/覆盖工具不会因为缺少的、未经测试的代码路径而引起您的注意!
最后,这里有一些类型杂耍的乐趣。甚至不包括数组或对象。
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)
下面是一个例子:
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中类型比较的更多参考,请参阅此内容。它应该给你一个清晰的理解。
False、Null、Nothing、0、Undefined等,等等。
其中每一个都有与实际概念相关的特定含义。有时,多个含义会被重载为单个关键字或值。
在C和C++中NULL
,False
和0
被重载为相同的值。在C#中,它们是 3 个不同的概念。
null
或NULL
通常表示缺乏价值,但通常不说明原因。
0
表示自然数 0 并且与1、2、3等具有类型等价性,并且在支持单独概念的语言中NULL
应该只处理数字。
False表示不真实。它用于二进制值。这并不意味着未设置,也不意味着0
. 它只是表示两个二进制值之一。
没有什么可以表明该值被明确设置为空,这表明与 null 相同,但有意图。
在某些语言中未定义表示该值尚未设置,因为没有代码指定实际值。
在 PHP 中,您可以使用 === 和 !== 运算符来检查值是否相等,以及它们的类型是否匹配。例如:0 == false
is true
,但是0 === false
is false
。!=
vs也是如此!==
。此外,如果您null
使用上述运算符与其他两个进行比较,请期待类似的结果。
现在在 PHP 中,通常在返回一个有时可能是0
(零)的值时使用这种值质量,但有时可能是函数失败。在 PHP 中的这种情况下,您返回false
并且必须使用身份运算符检查这些情况===
。例如,如果您正在搜索一个字符串在另一个字符串中的位置并且您使用strpos()
的是all, thenstrpos()
将返回false
,您在处理结果时必须考虑到这一点。
如果您将在您的函数中使用相同的技术,任何熟悉标准 PHP 库的人都会了解发生了什么以及如何检查返回的值是否是所需的值,或者在处理时是否发生了一些错误。函数参数实际上也是如此,您可以根据它们是数组还是字符串或不是什么来对它们进行不同的处理,并且这种技术在整个 PHP 中也大量使用,因此每个人都会很容易地掌握它。所以我想这就是力量。
我刚刚浪费了一天 1/2 的时间来尝试从0
, null
,false
中返回strops
!
这就是我试图做的所有事情,在我发现逻辑没有朝着正确的方向流动之前,似乎 php 编码中有一个黑洞:
概念采用托管在服务器上的域名,并确保它不是根级别,可以使用几种不同的方法来执行此操作,但由于我已经完成了其他 php 函数/构造,我选择了不同的方法。
无论如何,这是cosing的基础:
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
?
来自PHP 在线文档:
要将值显式转换为布尔值,请使用 (bool) 或 (boolean) 强制转换。
但是,在大多数情况下,强制转换是不必要的,因为如果运算符、函数或控制结构需要布尔参数,则值将自动转换。
转换为布尔值时,以下值被视为 FALSE:
- 布尔值
FALSE
本身 - 整数``0(零)
- 浮点数
0.0
(零) - 空字符串和字符串
"0"
- 一个元素为零的数组
- 具有零成员变量的对象(仅限 PHP 4)
- 特殊类型
NULL
(包括未设置的变量) - 从空标签创建的 SimpleXML 对象
考虑所有其他值TRUE
(包括任何资源)。
因此,在大多数情况下,它是相同的。
另一方面, the===
和 the==
不是一回事。通常,您只需要“等于”运算符。澄清:
$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 中学到的东西不一定适用于 Python、Perl 或 C 等。虽然学习你正在使用的语言的规则很有价值,但过度依赖它们是自找麻烦. 当下一个程序员需要维护您的代码并且您使用了一些结构来利用 Null 与 False 的一些小细节(例如)时,麻烦就来了。您的代码应该看起来是正确的(相反,错误的代码应该看起来是错误的)。
Null 在数据库中用于表示“无记录”或“无信息”。因此,您可能有一个描述“此用户是否希望我们向其发送电子邮件”的位字段,其中 True 表示他们愿意,False 表示他们不想发送任何内容,但 Null 表示您不想不知道。它们可以通过外部连接等来实现。
Null 的逻辑含义通常是不同的——在某些语言中,NULL 不等于任何东西,因此 if(a == NULL) 将始终为 false。
所以就我个人而言,我总是将一个布尔值初始化为 FALSE,而将一个布尔值初始化为 NULL 看起来有点恶心(即使在 C 中两者都只是 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 在他最近的 postcast 中谈到了它。但是尽量不要在你的例程中使用混合和匹配布尔与你的数据,你应该完全没问题。
关于 PHP 的一个有趣事实NULL
:如果你设置一个 var 等于NULL
,它就像你调用unset()
它一样。
NULL
本质上意味着一个变量没有赋值;false
是一个有效的布尔值,0
是一个有效的整数值,PHP 在0
、"0"
、""
和false
.
Null 什么都不是,False 有点,0 是(可能)32 位。
不是 PHP 专家,但在一些更现代的语言中,它们是不可互换的。我有点想念 0 和 false 可以互换,但是 boolean 是一种实际类型,你可以拥有与之关联的方法和对象,所以这只是一个权衡。虽然 Null 是 null,但本质上没有任何东西。
好吧,我从我的 PHP 时代记不起足够的答案来回答“===”部分,但是对于大多数 C 风格的语言,NULL 应该在指针值的上下文中使用,false 作为布尔值,零作为数值,例如 int。'\0' 是字符上下文的惯用值。我通常也更喜欢将 0.0 用于浮点数和双精度数。
所以.. 快速回答是:上下文。
在几乎所有现代语言中,null逻辑上指的是没有值的指针(或引用),或者没有初始化的变量。0 是零的整数值,而 false 是布尔值,好吧,假。为了使事情变得复杂,例如,在 C 中,null、0 和 false 都以完全相同的方式表示。我不知道它在 PHP 中是如何工作的。
然后,更复杂的是,数据库有一个 null 的概念,这意味着缺失或不适用,并且大多数语言没有直接的方法将 DBNull 映射到它们的 null。例如,直到最近,int 为 null 和为零之间没有区别,但是用可为 null 的 int 改变了这一点。
抱歉让这听起来很复杂。只是这多年来一直是语言中的一个难题,直到最近,它还没有任何明确的解决方案。人们过去常常只是将事物拼凑在一起,或者将数据库中的空白或 0 表示为空值,这并不总是能很好地工作。
False 和 0 在概念上相似,即它们是同构的。0 是自然数代数的初始值,False 是布尔代数的初始值。
换句话说,0 可以定义为一个数,当它与某个自然数相加时,会产生相同的数:
x + 0 = x
类似地,False 是一个值,它与任何其他值的析取是相同的值:
x || False = x
Null 在概念上是完全不同的东西。根据语言的不同,它有不同的语义,但没有一个将“初始值”描述为 False 和 0。Null 没有代数。它与变量有关,通常表示该变量在当前上下文中没有特定值。在大多数语言中,没有对 Null 定义操作,将 Null 用作操作数是错误的。在某些语言中,有一个称为“bottom”而不是“null”的特殊值,它是不终止计算值的占位符。
有人可以向我解释为什么 'NULL' 不仅仅是比较实例中的字符串?
$x = 0;
var_dump($x == 'NULL'); # TRUE !!!WTF!!!
虚假性的问题来自 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/