php empty 函数判断结果为空但实际值却为非空的原因解析
最近我在一个项目中使用 empty 时获取到了一些意料之外的结果。下面是我处理后的调试记录,在这里与你分享了。
var_dump( $user->uid, empty($user->uid) );
它的结果是:
string(5) "2955" bool(true)
结果出人意料。为什么变量的值为字符串,但同时会是空值呢?让我们在 $user->uid 变量上尝试使用其它一些函数来进行判断吧:
var_dump( $user->uid, empty($user->uid), isset($user->uid), is_null($user->uid) );
以上结果为:
string(5) "2955" bool(true) // empty bool(false) // isset bool(false) // is_null
is_null 函数执行结果符合预期判断,empty和isset函数返回了错误结果。
这里让我们来看看 user类的实现代码吧:
class User { 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 不是一个函数,而是一种语言结构。所以当将 $user->uid
传入 empty时,并不会先进行取值处理。而是会先判断 $user对象成员变量 uid的内容,由于这个变量并未真实存在,所以返回 false。
在正中应用场景下,如果你希望 empty 函数能够正常处理变量,我们需要在类中实现 __isset 魔术方法。
class User { 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( $user->uid, empty($user->uid) );
新的检测结果:
string(5) "2955" bool(false)
1.什么是语言结构
语言结构:就是PHP语言的关键词,语言语法的一部分;它不可以被用户定义或者添加到语言扩展或者库中;它可以有也可以没有变量和返回值。
2.语言结构执行速度快的原因
函数都要先被PHP解析器(Zend引擎)分解成语言结构,所以,函数比语言结构多了一层解析器解析,速度就相对慢了
3.php中语言结构有哪些
echo() print() die() isset() unset() include(),注意,include_once()是函数 require(),注意,require_once()是函数 array() list() empty()
4.怎样判断是语言结构还是函数
使用function_exists
eg:
function check($name){ if(function_exists($name)){ echo $name.'为函数'; }else{ echo $name.'为语言结构'; } }
5.语言结构与函数的区别 1.语言结构比对应功能的函数快 2.语言结构在错误处理上比较鲁棒,由于是语言关键词,所以不具备再处理的环节 3.语言结构不能在配置项(php.ini)中禁用,函数则可以。 4.语言结构不能被用做回调函数