tags:

views:

116

answers:

5

Considering that:

  • The isset() construct returns TRUE if a variable is set and not NULL
  • The is_null() function throws a warning if the variable is not set

Is there a way to test whether a variable exists, no matter it's NULL or not, without using the @ operator to suppress the notice?


EDIT

Together with your first replies, I've been thinking about this and I'm getting the conclusion that inspecting get_defined_vars() is the only way to distinguish between a variable set to NULL and an unset variable. PHP seems to make little distinctions:

<?php

$exists_and_is_null = NULL;

// All these are TRUE

@var_dump(is_null($exists_and_is_null));
@var_dump(is_null($does_not_exist));

@var_dump($exists_and_is_null===NULL);
@var_dump($does_not_exist===NULL);

@var_dump(gettype($exists_and_is_null)=='NULL');
@var_dump(gettype($does_not_exist)=='NULL');

?>
A: 
if (isset($var) && (is_null($var)) {
    print "\$var is null";
}

This should do the trick.

Davide Gualano
This condition is FALSE when $var is NULL
Álvaro G. Vicario
+6  A: 
$result = array_key_exists('varname', get_defined_vars());
thetaiko
Probably not optimal but witty
Álvaro G. Vicario
A: 

As you already found out, you cannot :

  • rely on isset, as it return false for a variable that's null.
  • use $not_exists===null, as it'll raise a notice.


But you could be able to use a combinaison of :


For instance :

$exists_and_null = null;
$exists_and_not_null = 10;

$defined_vars = get_defined_vars();

// true
var_dump(array_key_exists('exists_and_null', $defined_vars) 
    && $defined_vars['exists_and_null']===null);

// false
var_dump(array_key_exists('exists_and_not_null', $defined_vars) 
    && $defined_vars['exists_and_not_null']===null);

// false
var_dump(array_key_exists('not_exists', $defined_vars) 
    && $defined_vars['not_exists']===null);


A couple of notes :

  • In the first case, the variable exists => there is an entry in the list returned by get_defined_vars, so the second part of the condition is evaluated
    • and both parts of the condition are true
  • In the second case, the variable exists too, but is null
    • which means the first part of the condition is true, but the second one is false,
    • so the whole expression is false.
  • In the third case, the variable doesn't exist,
    • which means the first part of the condition is false,
    • and the second part of the condition is not evaluated -- which means it doesn't raise a notice.

But note this is probably not that a good idea, if you care about performances : isset is a language construct, and is fast -- while calling get_defined_vars is probably much slower ^^

Pascal MARTIN
Excellent analysis. In practical terms, using @ looks like the best option.
Álvaro G. Vicario
Thanks :-) ;;; In practical terms, I would say there is generally no need to make a difference between *"doesn't exist"* and *"is null"* : in most cases, using `isset` should be just fine.
Pascal MARTIN
A: 

I used a self created function to check this easily, keep in mind it will fire off a PHP warning (I only monitor E_ERROR when I develop).

/**
 * isNullOrEmpty()
 * 
 * @global Returns a boolean letting you know if a value is null or empty
 * @param mixed $arg
 * @return
 */
    function isNullOrEmpty( $arg )
    {
        if ( !is_array( $arg ) )
        {
            $arg = array( $arg );
        }

        foreach ( $arg as $key => $value )
        {
            $value = trim($value);
            if( $value == "" || $value == null )
            {
                return true;
            }
        }
        return false;
    }
TravisO
A: 

I would argue here that any code requiring such a comparison would have gotten its semantics wrong; NULL is an unset value in a language that has no straightforward way of distinguishing between the two.

aib
There is a difference between (e.g.) having an unset $phone_number (the user hasn't provided his number) and having a typo like $fone_number in your code. I find nothing wrong in handling both cases differently and IMHO it's pretty peculiar than PHP makes so little difference. Just look at SQL: a row with a NULL value is not the same as a non-existing row.
Álvaro G. Vicario
Of course there is. Yet, try to explain that to PHP. And don't even get me started on not being able to capture simple mistakes such as a typo (reading an unset variable) or passing the wrong number of parameters...
aib
There - now the second sentence is stressed a lot more.
aib