百科狗-知识改变命运!
--

empty() - php 变量处理函数

乐乐12个月前 (11-21)阅读数 10#技术干货
文章标签变量

empty()

(PHP 4, PHP 5, PHP 7)

检查一个变量是否为空

说明

empty(mixed $var): bool

empty() - php 变量处理函数

判断一个变量是否被认为是空的。当一个变量并不存在,或者它的值等同于FALSE,那么它会被认为不存在。如果变量不存在的话,empty()并不会产生警告。

参数

$var

待检查的变量

Note:

在 PHP 5.5 之前,empty()仅支持变量;任何其他东西将会导致一个解析错误。换言之,下列代码不会生效:empty(trim($name))。作为替代,应该使用trim($name)== false.

没有警告会产生,哪怕变量并不存在。这意味着empty()本质上与!isset($var)||$var == false等价。

返回值

当$var存在,并且是一个非空非零的值时返回FALSE否则返回TRUE.

以下的东西被认为是空的:

  • ""(空字符串)
  • 0(作为整数的0)
  • 0.0(作为浮点数的0)
  • "0"(作为字符串的0)
  • NULL
  • FALSE
  • array()(一个空数组)
  • $var;(一个声明了,但是没有值的变量)

更新日志

版本说明
5.5.0

empty()现在支持表达式了,而不仅仅是变量。

5.4.0

检查非数字的字符串偏移量会返回TRUE.

范例

一个简单的empty()与isset()的比较。

在字符串偏移量上使用empty()

PHP 5.4 修改了当传入的是字符串偏移量时,empty()的行为

以上例程在PHP 5.3中的输出:

bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)

以上例程在PHP 5.4中的输出:

bool(true)
bool(false)
bool(false)
bool(false)
bool(true)
bool(true)

注释

Note:因为是一个语言构造器而不是一个函数,不能被可变函数调用。

Note:

当对一个不可见的对象属性使用empty()时,__isset()方法如果存在的话,它将会被调用。

参见

  • isset() 检测变量是否已设置并且非 NULL
  • __isset()
  • unset() 释放给定的变量
  • array_key_exists() 检查数组里是否有指定的键名或索引
  • count() 计算数组中的单元数目,或对象中的属性个数
  • strlen() 获取字符串长度
  • The type comparison tables
Please note that results of empty() when called on non-existing / non-public variables of a class are a bit confusing if using magic method __get (as previously mentioned by nahpeps at gmx dot de). Consider this example:

The result for empty($registry->notEmpty) is a bit unexpeced as the value is obviously set and non-empty. This is due to the fact that the empty() function uses __isset() magic functin in these cases. Although it's noted in the documentation above, I think it's worth mentioning in more detail as the behaviour is not straightforward. In order to achieve desired (expexted?) results, you need to add __isset() magic function to your class:

It actually seems that empty() is returning negation of the __isset() magic function result, hence the negation of the empty() result in the __isset() function above.
When you need to accept these as valid, non-empty values:
- 0 (0 as an integer)
- 0.0 (0 as a float)
- "0" (0 as a string)

This is similar to Rails' blank? method.
I'm summarising a few points on empty() with inaccessible properties, in the hope of saving others a bit of time. Using PHP 5.3.2.

As expected, this gives "Fatal error: Cannot access private property MyClass::$foo".
But substitute the line
if (empty($myClass->foo)) echo 'foo is empty'; else echo 'foo is not empty';
and we get the misleading result "foo is empty". 
There is NO ERROR OR WARNING, so this is a real gotcha. Your code will just go wrong silently, and I would say it amounts to a bug.
If you add two magic functions to the class:
public function __get($var) { return $this->$var; }
public function __isset($var) { return isset($this->$var); }
then we get the expected result. You need both functions.
For empty($myClass->foo), I believe PHP calls __isset, and if that is true returns the result of empty on the result of __get. (Some earlier posts wrongly suggest PHP just returns the negation of __isset).
BUT …
See the earlier post by php at lanar dot com. I confirm those results, and if you extend the test with isset($x->a->b->c) it appears that __isset is only called for the last property in the chain. Arguably another bug. empty() behaves in the same way. So things are not as clear as we might hope.
See also the note on empty() at
http://uk3.php.net/manual/en/language.oop5.overloading.php
Clear as mud!
So remember to trim your strings first! 
To add on to what anon said, what's happening in john_jian's example seems unusual because we don't see the implicit typecasting going on behind the scenes. What's really happening is:
$a = '';
$b = 0;
$c = '0';
(int)$a == $b -> true, because any string that's not a number gets converted to 0
$b==(int)$c -> true, because the int in the string gets converted
and
$a==$c -> false, because they're being compared as strings, rather than integers. (int)$a==(int)$c should return true, however.
Note: I don't remember if PHP even *has* typecasting, much less if this is the correct syntax. I'm just using something for the sake of examples.
If you want to use empty() to evaluate an expression (not a variable), and you don't have PHP 5.5+, you can do it by wrapping the call to empty in a function, like so:

Then you can do something like

without issue, since the local variable $var is being tested rather than the expression in the function call itself.
test if all multiarray's are empty

OUTPUT:
========
0 is_multiArrayEmpty= 1
1 is_multiArrayEmpty= 1
2 is_multiArrayEmpty= 1
3 is_multiArrayEmpty= 1
4 is_multiArrayEmpty= 1
5 is_multiArrayEmpty= 1
6 is_multiArrayEmpty= 1
7 is_multiArrayEmpty= 1
8 is_multiArrayEmpty= 1
9 is_multiArrayEmpty= 
10 is_multiArrayEmpty= 
11 is_multiArrayEmpty= 
12 is_multiArrayEmpty=
empty() should not necessarily return the negation of the __isset() magic function result, if you set a data member to 0, isset() should return true and empty should also return true. A simpler implementation of the __isset magic function would be:
public function __isset($key) {
 return isset($this->{$key});
}
I don't understand why this isn't included in stdClass and inherited by default.
I'm comparing behavior of `!` and `empty()`, find an undocumented behavior here.
just like cast-to-boolean, `empty()` cares about if SimpleXML object is made from emty tags.
`empty(simplexml_load_string(''))` is TRUE
this behavior begins from php 5.1.0~7, in 5.0.x that's FALSE
proof here => https://3v4l.org/74Tc4
Be careful, if "0" (zero as a string), 0 (zero as an integer) and -0 (minus zero as an integer) return true, "-0" (minus zero as a string (yes, I already had some customers that wrote -0 into a form field)) returns false. You need to cast your variable before testing it with the empty() function : 
Note that checking the existence of a subkey of an array when that subkey does not exist but the parent does and is a string will return false for empty. 
i.e. 

This is correct, per the documentation (http://php.net/manual/en/language.types.string.php); quite a bit down the page is the Warning: "Writing to an out of range offset pads the string with spaces. Non-integer types are converted to integer." ) I didn't receive a warning but perhaps that's correct too...depends on whether the string -> integer conversion is considered "illegal": "Illegal offset type emits E_NOTICE."
(i.e. since $params['search'] is a string, the 'filter' subscript is converted to 0, so the test becomes empty($params['search'][0]), which is obviously false), but it tripped me up enough to mistakenly file a bug report (which I've since closed).
Calling non existing object property, empty($object->prop), will trigger __isset(), the same way as isset($object->prop) does, but there is one difference. If __isset() returns TRUE, another call to __get() will be made and actual return value will be result of empty() and result of __get().
(experienced in PHP 5.6.3) The `empty()` can't evaluate `__get()` results explicitly, so the `empty()` statement bellow always renders true

The correct way is to force the evaluation of `__get()` first, by using extra braces around implicit statements like this:

So if you are using packages that utilize object oriented designs and magic methods like `__get()`, it's a good practice to always use double braces for `empty()` calls.
In reply to "admin at ninthcircuit dot info",
Using str_replace is unnecessary. I would encourage the use of trim which would most likely be faster (haven't tested) and easier. Trim also takes care of other white space like line breaks and tabs. Actually, in most of the applications I code, I use a multi-dimensional array map function with trim on the Super Globals such as $_POST, $_GET and $_COOKIE as so far, there hasn't been an instance where I would want any user input to begin or end with whitespace. The good thing about doing this is that you never have to worry about 'trimming' your input which makes your code easier and more reliable (incase you forget to trim some input).
I can't use empty() in all situations because '0' is usually not considered empty to me. I did a quick benchmark over the most common ways of testing it. '' == var suffers from '' == 0 is true so that's just there for curiosity.

The results:
Total time 0 == mb_strlen(var): 3.141s
Total time 0 === strlen(var): 2.904s
Total time 0 == strlen(var): 2.878s
Total time '' == var: 1.774s
Total time '' === var: 1.706s
Total time empty(var): 1.496s
Thus '' === var will be my zero length string test.
Warning: an "empty" object is NOT considered to be empty

I don't know if there is a standard way to test for "empty" objects, I personally use array casting: 
Simple solution for: "Fatal error: Can't use function return value in write context in ..." 
Since I didn't like how empty() considers 0 and "0" to be empty (which can easily lead to bugs in your code), and since it doesn't deal with whitespace, i created the following function:

Instead of saying if (!empty($var)) { // it's not empty } you can just say if (check_not_empty($var)) { // it's not empty }.
If you want strings that only contain whitespace (such as tabs or spaces) to be treated as empty then do: check_not_empty($var, 1)
If you want to check if a string IS empty then do: !check_not_empty($var).
So, whenever you want to check if a form field both exists and contains a value just do: if (check_not_empty($_POST['foo'], 1))
no need to do if (isset() && !empty()) anymore =]
Note the exceptions when it comes to decimal numbers:

For those of you using MySQL, if you have a table with a column of decimal type, when you do a SELECT, your data will be returned as a string, so you'll need to do apply intval() before testing for empty.
e.g.
TABLE t has columns id MEDIUMINT and d DECIMAL(4,2)
and contains 1 row where id=1, d=0.00 
To make an empty function, which only accepts arrays, one can use type-hinting:

Type hinting is a good thing to use in your code, because it makes it more easy to reason about your code. Besides that, it automatically documents the code.
empty($var) will return TRUE if $var is empty (according to the definition of 'empty' above) AND if $var is not set.
I know that the statement in the "Return Values" section of the manual already says this in reverse:
"Returns FALSE if var has a non-empty and non-zero value." 
but I was like "Why is this thing returning TRUE for unset variables???"... oh i see now... Its supposed to return TRUE for unset variables!!! 
David from CodeXplorer:
>> The ONLY reason to use empty() is for code readability. It is the same as an IF/ELSE check.
>> So, don't bother using EMPTY in the real world.
This is NOT true. empty() will not generate warnings if you're testing against an undefined variable as a simple boolean check will. On production systems, warnings are usually shut off, but they are often active on development systems.
You could test a flag with
  
but this can generate a warning if $flagvar is not set.
Instead of 
  
you can simply use
  
for easy readability without warnings.
Here's what I do for the zero issue issue:
if($val == '' && $val !== 0 && $val !== '0')
in cases when "0" is not intended to be empty, here is a simple function to safely test for an empty string (or mixed variable): 
Note on the selfmade empty function below:
function_exists() returns false on language constructs and empty is a language construct.
Note that if your variable only has an "end of line" (aka carriage return), PHP_EOL it is not considered as empty. Since end of lines are not always easy to spot this can be confusing.
For 100,000,000 comparisons, here are the results against PHP 7.2.16 on my hardware:
count($test): 2.697 sec
count($test2): 2.596 sec
$test === array(): 2.579 sec
$test2 === array(): 2.552 sec
empty($test): 3.085 sec
empty($test2): 3.113 sec
In short, it doesn't matter what method is used although empty() is actually just ever so slightly slower despite it being a language construct. YMMV.
Note that empty() will return false on null byte. Eg.

Output : 1
If you test an element of an array (like $_POST['key]), it test if the key doesn't exist or if it exist if its value is empty and never emit a warning.
For who don't want to test what happen if passed an array element here is my test and result.

And the result is:
  A empty - B empty - C empty - D not empty
For the verification of a form, to "block" entries such as a simple space or other, I thought of this combination:
function isEmpty($string){
  $val = preg_replace('#[^A-Za-z0-9]+#', '', $string) ;
  $val = trim($string, '');
  return ($string=='') ;
}
This protects entries like: ' ' ,' - ', '. - +', ... On entries like name, profession, ... it's helpful

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)