资讯专栏INFORMATION COLUMN

为什么 php empty 函数判断结果为空,但实际值却为非空

jimhs / 838人阅读

摘要:为什么变量的值为字符串,但同时会是空值呢让我们在变量上尝试使用其它一些函数来进行判断吧以上结果为译者注这边的结果可能存在问题的结果同样为,可以到这里去运行下查看结果。和函数执行结果符合预期判断,唯独函数返回了错误结果。

本文首发于 震惊 php empty 函数判断结果为空,但实际值却为非空,转载请注明出处。

最近我在一个项目中使用 empty 时获取到了一些意料之外的结果。下面是我处理后的调试记录,在这里与你分享了。

var_dump(
    $person->firstName,
    empty($person->firstName)
);

它的结果是:

string(5) "Freek"
bool(true)

结果出人意料。为什么变量的值为字符串,但同时会是空值呢?让我们在 $person->firstName 变量上尝试使用其它一些函数来进行判断吧:

var_dump(
    $person->firstName,
    empty($person->firstName),
    isset($person->firstName),
    is_null($person->firstName)
);

以上结果为:

string(5) "Freek"
bool(true) // empty
bool(true) // isset
bool(false) // is_null
译者注:这边的结果可能存在问题 isset 的结果同样为 false,可以到 这里 去运行下查看结果。

issetis_null 函数执行结果符合预期判断,唯独 empty 函数返回了错误结果。

这里让我们来看看 person 类的实现代码吧:

class person
{
    protected $attributes = [];

    public function __construct(array $attributes)
    {
        $this->attributes = $attributes;
    }

    public function __get($name)
    {
        return $this->attributes[$name] ?? null;
    }
}

从上述代码我们可以看到 Person 对象的成员变量是通过 __get 魔术方法从 $attributes 数组中检索出来的。

当将变量传入一个普通函数时,$person->firstName 会先进行取值处理,然后再将获取到的结果作为参数传入函数内。

但是 empty 不是一个函数,而是一种数据结构。所以当将 $person->firstName** 传入 **empty** 时,并不会先进行取值处理。而是会先判断 **$person 对象成员变量 firstName 的内容,由于这个变量并未真实存在,所以返回 false

在正中应用场景下,如果你希望 empty 函数能够正常处理变量,我们需要在类中实现 __isset 魔术方法。

class Person
{
    protected $attributes = [];

    public function __construct(array $attributes)
    {
        $this->attributes = $attributes;
    }

    public function __get($name)
    {
        return $this->attributes[$name] ?? null;
    }

    public function __isset($name)
    {
        $attribute = $this->$name;

        return !empty($attribute);
    }
}

这是当 empty 进行控制判断时,会使用这个魔术方法来判断最终的结果。

再让我们看看输出结果:

var_dump(
   $person->firstName, 
   empty($person->firstName)
);

新的检测结果:

string(5) "Freek"
bool(false)

完美!

原文:When empty is not empty

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/28707.html

相关文章

  • Emptiness 空值语义

    摘要:原文作者译者如果里的数组不能为空仔细想想如果已经设计了非空的数组了但这会让人很烦对吧什么语言有非空的数组然而比起语言已经修改了很多规则了例如里不需要了甚至可以使用来把几个连接起来没有了操作符它是那么的让人迷惑多余并且没了它语言会变得更好还有 原文: Emptiness作者: Soroush Khanlou译者: kemchenj 如果 Swift 里的 array 数组不能为空? 仔细...

    Mertens 评论0 收藏0
  • Kotlin可空性探索

    摘要:可空性在中,类型系统区分一个引用是可以容纳可空引用还是不能容纳非空引用。使用可以很方便得将可空转为非空,但可空变量值为,则会。 目录介绍 01.可空性 02.安全调用运算符:?. 03.Elvis运算符:?: 04.安全转换运算符:as? 05.非空断言:!! 06.let函数说明 07.可空类型的扩展 08.Java中判断方式 09.kotlin是否解决NPE 10.kotlin如...

    DataPipeline 评论0 收藏0
  • Kotlin如何避免“!!”(非空断言)

    摘要:当我们把自动转成的时候,代码里会出现很多非空断言。如何避免使用这种是最常用的方法,也是首选的方法。由于是变量,为了避免多线程对变量的修改而出现的情况,从编译上进行了限制。代理属性如果需要对基本类型等做非空处理,可以使用代理属性。 当我们把Java自动转成Kotlin的时候,代码里会出现很多非空断言!!。或者某些场景下因为IDE提示或编译错误,也让我们自己加上了一些!!。但使用!!的后果...

    zhongmeizhi 评论0 收藏0
  • 《Java8实战》-第十章笔记(用Optional取代null)

    摘要:是第一批在堆上分配记录的类型语言之一。实际上,的这段话低估了过去五十年来数百万程序员为修复空引用所耗费的代价。很明显,这种方式不具备扩展性,同时还牺牲了代码的可读性。是目前程序开发中最典型的异常。完成这一任务有多种方法。 用Optional取代null 如果你作为Java程序员曾经遭遇过NullPointerException,请举起手。如果这是你最常遭遇的异常,请继续举手。非常可惜,...

    flybywind 评论0 收藏0
  • js 中二叉树的深度遍历与广度遍历(递归实现与非递归实现)

    摘要:树中结点的最大层次称为树的深度或高度。二叉树有深度遍历和广度遍历,深度遍历有前序中序和后序三种遍历方法。二叉树的前序遍历可以用来显示目录结构等中序遍历可以实现表达式树,在编译器底层很有用后序遍历可以用来实现计算目录内的文件及其信息等。 树的简介 栈、队列、链表等数据结构,都是顺序数据结构。而树是非顺序数据结构。树型结构是一类非常重要的非线性结构。直观地,树型结构是以分支关系定义的层次结...

    Yuanf 评论0 收藏0

发表评论

0条评论

jimhs

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<