tags:

views:

975

answers:

9

PHP has the habit of evaluating (int)0 and (string)"0" as empty when using the empty() function. This can have unintended results if you expect numerical or string values of 0. How can I "fix" it to only return true to empty objects, arrays, strings, etc?

A: 

I created an IsEmpty() a terse quick function.

function IsEmpty($mData) {
    return is_int($mData) ? false : 
        is_string($mData) ? $mData=="" : 
        empty($mData);
}
null
Answering your own question before seeing any other responses? -- Your solution conflates everything into one complex statement, effectively obfuscating it (not considered good style in most places).
le dorfier
@le dorfier: there's no problems with answering your own questions: it's just creating more information for others to read and learn by.@null: one of the key benefits of using empty() is that you can test undefined variables without causing a warning. this function doesn't have this same ability.
nickf
+2  A: 

"Fixing" is one point of view. Another would be to assume it's not "broken", and learn to work with it the way it was intentionally designed.

Given the problem as you describe it, the best thing would be to tighten up your code so the variable can't be put into an indeterminate type state. Otherwise, you'll want to test for datatype using gettype().

le dorfier
From what I understand it is now recommended that one use is_x rather than the older gettype() function.
Noah Goodrich
The problem is the OP appears to want a type-independent solution. With PHP, the complete enumeration of is_? options may change. It's far better to avoid the train wreck in the first place. Actually, what they probably want is points for an abstract question. :)
le dorfier
+1 for the points fishing comment. It does seem like the OP was a little quick with their own solution to a non-existent problem. Still, if you want a type independent solution I would use "===" operator instead.
Noah Goodrich
Right, and even then a type-independent solution is a bad thing to want in the first place.
le dorfier
+6  A: 

I seldom use empty() for the reason you describe. It confuses legitimate values with emptiness. Maybe it's because I do a lot of work in SQL, but I prefer to use NULL to denote the absence of a value.

PHP has a function is_null() which tests for a variable or expression being NULL.

$foo = 0;
if (is_null($foo)) print "integer 0 is null!\n"; 
else print "integer 0 foo is not null!\n";

$foo = "0";
if (is_null($foo)) print "string '0' is null!\n"; 
else print "string '0' is not null!\n";

$foo = "";
if (is_null($foo)) print "string '' is null!\n"; 
else print "string '' is not null!\n";

$foo = false;
if (is_null($foo)) print "boolean false is null!\n"; 
else print "boolean false is not null!\n";

You can also use the exactly equals operator === to do a similar test:

if ($foo === null) print "foo is null!\n";

This is true if $foo is NULL, but not if it's false, zero, "", etc.

Bill Karwin
+2  A: 

Generally speaking you want to use the triple equals operator to determine when a value truly is null or false. This is more specific and the results ALWAYS return exactly as expected.

Creating a separate function to do something that you can do in a single line of code but using a different operator seems to be overly complicated and adds additional obfuscation.

Additionally, many programmers tend to use 0 or an empty string to denote a non-existent value but it is more correct (and I feel a better practice) to use a null value to denote any value (regardless of type) that is truly non-existent.

Noah Goodrich
The real problem with it IMHO is that it discards precision and abets sloppy thinking.
le dorfier
In SQL as Bill pointed out, NULL is a non-existent value and an empty string is an empty string. I like to check for NULL's explicitly as well as invalid strings and integers depending on the needs of the program.
Noah Goodrich
In other words, sometimes a zero or empty string is valid but these should be tested independent of a test for null values
Noah Goodrich
+1  A: 

"0" is always considered false (or empty) in PHP, and it does make alot of sense (not that I'll argue that here). If you want to have zero evaluate to true as well, use strlen($value).

too much php
Good advice, although you'll probably want to throw a trim() around $value.
Alan Storm
A: 

The most effective solution for this problem is to test if the variable is false e.g.


if (!$variable_name) {echo $variable_name;}

It doesn't matter if the variable is empty or null, it all equals to false when put in a if conditional.

Nikola Stjelja
that's pretty much the same as empty(), in that 0 or "0" will be false, which is what the OP was trying to avoid.
nickf
also throws a strict notice if the variable is not set
monzee
It's also slightly more obfuscated over empty(). I'd advise against this, unless the variables is only true or false.
staticsan
+1  A: 

here there are a good docs about how to read the NULL value. take a look

http://ar2.php.net/manual/en/types.comparisons.php

Gabriel Sosa
A: 

I use it like this

if (empty($variable) && '0' != $variable) {
  // Do something
}
Marv3lz
A: 

You're trying to use empty() for something it's not intended for. Personally, I think it's behaviour comes from an older programming paradigm in PHP and it could probably be retired.

Instead, make your checks more explicit. Rather than checking if the value is not useful, check that it is. For example, if you want an array, check it's an array (is_array()) rather than checking whether it's a string.

Also, you can rely on the fact that all $_POST and $_GET variables are strings, so you can make comparisons to "", or check that strlen() == 0.

staticsan