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个回答

244

针对PHP语言而言:

Null 表示 "无任何值",这个变量还没有被初始化。

False 表示 "在布尔运算环境下为假",用于明确表达你正在处理逻辑问题。

0 是一个 int 类型,与上述两个不同,用于数学计算。

动态语言(如 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(根本没有设置,将导致难以调试)。


41
关于Null的注意事项:PHP将其用作“无值”,但这不是一个好的习惯。通常,Null表示“未知值”,这与“无值”或“未初始化变量”是不同的。任何数加1都是1,而未知值加一仍然是未知值。请记住,任何运算符应用于null都将(应该)导致null,因为对“未知值”的任何操作都会产生未知值。 - Eli
8
请注意,这些都是“意图”,与现实发生的事情无关。在现实中,函数可以针对不存在的值(例如strpos、input_filter)返回false,并且针对失败(例如input_filter)返回null。因此,答案是,在阅读特定函数文档后,使用===false和/或===null。 - gcb
5
@Eli: 你是从哪里得到“Null”通常意味着“未知值”的想法的呢?我想不出任何编程语言普遍适用这个定义,至少按照我能找到或听到的任何定义,“Null”并不意味着这个。也许你知道我不知道的东西? - iconoclast
2
@iconoclast - 我们来看一下数据库领域。据我所知,null被用作占位符,表示数据库中不存在或未知的数据值。请参考http://dev.mysql.com/doc/refman/5.0/en/working-with-null.html 或 http://en.wikipedia.org/wiki/Null_%28SQL%29。 - Eli
2
Eli没有错。他说的是语义上,当你使用null时,你向其他程序员发出信号,表明你不知道里面有什么。它是未定义的。而当你使用0时,你表明你知道里面有什么:一个数字。这里的数字表示缺少东西。请记住,无论PHP如何处理值,值都承载着意义,值是一种文档形式。 - Bite code
显示剩余7条评论

52
null 就是 nullfalse 就是 false。虽然 PHP 设计上希望更加一致(在这里的精选答案中有概述),但实际情况并不如此,特别是当考虑到一些方法返回的 false/null 的时候会变得很混乱(不易理解)。一些方法会用 null 而已经使用了 false,例如 filter_input()。如果变量未通过过滤,则它们返回 false,如果变量不存在,则返回 null (不存在是否也意味着未通过过滤?)。

当作者关心失败类型时,方法可以交替返回 false/null/string 等,例如,在 filter_input() 中,如果您关心验证失败的原因,则可以检查 ===false===null。但是,如果您没有注意到,这可能是一个陷阱,因为如果他们只记得编写 ===false 的测试用例,则可能会忘记添加对 ===null 的检查。大多数 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)

31
我认为0等于null是完全无稽之谈,因为0是一个值而null是表示变量未初始化的标志。感谢PHP团队。 - mercsen
2
你重复了两次以 var_dump( null == 0 ); 开头的代码部分。 - Sparky
2
在 PHP 中真正奇怪的是:null < -1 => TRUE。 - thehpi
1
@mercsen 至少如果 PHP 始终像 0 == null 那样表现,我会对它感到满意。奇怪的是,0 == nullnull == [],但是 [] != 0 !! - nawfal
1
在我看来,strrpos('fail', 'search') 返回 false 而不是 null 是正确的。如果 null 表示未知,则 strrpos 返回 null 就像它在说“我不知道字符串是否存在”而不是“字符串不存在”。 - Eborbob
显示剩余4条评论

36

以下是一个示例:

            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类型比较,这将使您更加清楚地了解。


7
在PHP中,你可以使用 === 和 !== 运算符来检查值是否相等,以及它们的类型是否匹配。例如:0 == falsetrue,但是 0 === falsefalse。同样的,!= 与 !== 也是如此。如果你使用上述运算符将 null 与其他两个值进行比较,结果也会类似。
在PHP中,通常会使用这种值的特性来返回一个值,有时可能是 0(零),但有时可能是函数失败了。在这种情况下,在PHP中返回 false,并且必须使用恒等运算符 === 检查这些情况。例如,如果你正在搜索一个字符串在另一个字符串中的位置,并且你正在使用 strpos(),这个函数将返回数字位置,如果字符串位于开头,位置可能为 0,但如果根本没有找到字符串,则 strpos() 将返回 false,在处理结果时必须考虑到这一点。
如果你在你的函数中使用相同的技术,任何熟悉标准PHP库的人都会理解发生了什么以及如何检查返回值是否是所需的,或者在处理过程中是否出现了错误。实际上,对于函数参数也是如此,你可以根据它们是数组还是字符串或其他类型进行不同的处理,这种技术在PHP中也被广泛使用,因此每个人都可以很容易地理解。所以我想这就是它的力量。

5

False, Null, Nothing, 0, Undefined,等等。

每个关键词或值都有特定含义与实际概念相关,有时一个单词或值会承担多重含义。

CC++中,NULLFalse0被重载为同一值。在C#中,它们是三种不同的概念。

nullNULL通常表示缺少值,但通常并不指明原因。0表示自然数零,与1、2、3等类型等效,并且在支持单独概念的语言中应仅视为一个数字。

False表示非真。它用于二进制值。它并不意味着未设置,也不意味着0。它只是表示两个二进制值之一。

Nothing可以表示特别设置为空值,这与null相同,但具有明确的意图。

在某些语言中,Undefined表示尚未设置该值,因为没有代码指定实际值。


有趣,但完全没有讨论PHP。 - Brad

4

我刚刚浪费了半天的时间,试图让 strops 返回 0null 或者 false

这是我一直在尝试做的事情,在我发现逻辑方向不对之前,似乎 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"; 
    }
}

感谢这篇文章,我现在明白即使是圣诞节,也不一定是true,因为它也可能是一个null的日子!
浪费了一整天时间来调试一些简单的代码后,我希望之前就知道这个,因为我本可以找到问题所在,而不是到处寻找解决方法。它没有工作,因为FalseNULL0都不同于True或False或NULL

2

根据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在线文档中的“比较运算符”页面。

希望这可以帮助您。


1
这些值之间的差异总是归结于详细的语言特定规则。你在PHP中学到的并不一定适用于Python、Perl或C等其他语言。虽然学习你正在使用的语言的规则很有价值,但过度依赖它们会带来麻烦。当下一个程序员需要维护你的代码时,你使用了一些利用Null与False之间某些小细节的构造,这就会出现问题。你的代码应该看起来正确(反之,错误的代码应该看起来错误)。

1

在数据库中,Null用于表示“没有记录”或“没有信息”。因此,您可能会有一个位字段,描述“这个用户是否想通过我们发送电子邮件”,其中True表示他们想要,False表示他们不想收到任何东西,但是Null表示您不知道。它们可以通过外部连接等方式产生。

Null的逻辑含义通常是不同的-在某些语言中,NULL不等于任何东西,因此if(a == NULL)将始终为false。

所以个人认为我总是将布尔值初始化为FALSE,并且将其初始化为NULL看起来有点奇怪(即使在C中两者都只是0...只是一种风格问题)。


1

在PHP中,这取决于您是否验证类型:

( 
 ( false !== 0 ) && ( false !== -1 ) && ( false == 0 ) && ( false == -1 ) &&
 ( false !== null ) && ( false == null ) 
)

从技术上讲,null 是 0x00,但在 PHP 中,( null == 0x00 ) && ( null !== 0x00 )

0 是一个整数值。


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