Reputation: 8563
Is there a single function that can be created to tell whether a variable is NULL or undefined in PHP? I will pass the variable to the function (by reference if needed) but I won't know the name of the variable until runtime.
isset()
and is_null()
do not distinguish between NULL and undefined.
array_key_exists
requires you to know the name of the variable as you're writing your code.
And I haven't found a way to determine the name of a variable without defining it.
I've also realized that passing a variable by reference automatically defines it.
Through the collection of these answers and comments I've determined that the short answer to my question is "No". Thank you for all the input.
Here are some details on why I needed this:
I've created a PHP function called LoadQuery()
that pulls a particular SQL query from an array of queries and then prepares it for submission to MySQL. Most-importantly I scan the query for variables (like $UserID
) that I then replace with their values from the current scope. In creating this function I needed a way to determine if a variable had been declared, and was NULL, empty, or had a value. This is why I may not know the name of the given variable until runtime.
Upvotes: 12
Views: 15886
Reputation: 21
Based on some of the answers here I came up with this function to check for whether a field was present in an array. I wanted to be able to distinguish between a field being absent vs present and null and found that isset()
and is_null
gave the same results.
function isArrayFieldPresent($array, $field)
{
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});
try {
try {
$test = $array[$field];
return true;
} catch (ErrorException $e) {
return false;
}
} finally {
restore_error_handler();
}
}
Originally this was inline but I wanted to move it to a function but you can't pass an undeclared variable or array reference so I found I could pass it as the array and the desired field separately.
Upvotes: 0
Reputation: 1534
In PHP 5.2 or greater, I guess it is possible as follows:
// checking a variable (before and after it is defined)
$var_status1 = @is_defined( $variable, __LINE__, __FILE__ ); // don't put any additional code on this line
$variable = NULL;
$var_status2 = @is_defined( $variable, __LINE__, __FILE__ ); // don't put any additional code on this line
function is_defined( $var, $line, $file ) {
$e = error_get_last();
if ( $e !== NULL && $e['type'] === 8 && $e['line'] === $line && $e['file'] === $file ) {
return 'Undefined';
} else {
return 'Defined';
}
}
echo $var_status1 . '<br>';
echo $var_status2 . '<br>';
Note: I did not have time to test this solution in all possible situations (I just use it in a plugin I developed), so everyone is invited to find a flaw here.
Upvotes: 0
Reputation: 24146
Using modified example from PHP - Differenciate an undefined variable from a null variable
we can differentiate it:
$v1 = null;
echo (isset($v1) ? '$v1 set' : '$v1 not set') . PHP_EOL;
echo (is_null($v1) ? '$v1 null' : '$v1 not null') . PHP_EOL;
echo (empty($v1) ? '$v1 empty' : '$v1 not empty') . PHP_EOL;
echo (array_key_exists('v1', get_defined_vars()) ? '$v1 defined' : '$v1 not defined') . PHP_EOL;
echo PHP_EOL;
echo (isset($v2) ? '$v2 set' : '$v2 not set') . PHP_EOL;
echo (@is_null($v2) ? '$v2 null' : '$v2 not null') . PHP_EOL;
echo (empty($v2) ? '$v2 empty' : '$v2 not empty') . PHP_EOL;
echo (array_key_exists('v2', get_defined_vars()) ? '$v2 defined' : '$v2 not defined') . PHP_EOL;
prints:
$v1 not set
$v1 null
$v1 empty
$v1 defined
$v2 not set
$v2 null
$v2 empty
$v2 not defined
we can use array_key_exists(..., get_defined_vars())
and is_null(...)
to detect both situations
Upvotes: 6
Reputation: 890
what about this?
try {
$undefined_var
} catch (Exception $ex) {
$is_undefined = true;
}
if(empty($is_undefined)){ ... }
Upvotes: -1
Reputation: 8563
Essentially the answer is no. There is not a single function you can create that will tell whether a runtime variable is null or is undefined. (by 'runtime variable' I mean a variable who's name you don't yet know at the time of coding. See Elaboration in the question above).
Relevant Observations:
array_key_exists('variable_name', $GLOBALS)
as @zzzzBov stated, to see if a variable has been declared, but only if you know the name of the variable at coding time.Possible 'Dirty' Solutions
As @Phil (and @zzzzBov) explained you could use a messy trick of capturing error messages that would get thrown when you reference an undeclared variable.
I also considered a method where you: Make note of all the keys in $GLOBALS
, then store a unique value in your target variable (recording it's original value first for later use). And then search $GLOBALS
looking for that unique value to determine the name of the variable AND (by comparing with your earlier look at $GLOBALS
) determine if the variable existed before. But this also seems messy and unreliable.
Upvotes: 3
Reputation: 11
You can get an array of the defined variables in the current scope with:
get_defined_vars();
Upvotes: 1
Reputation: 179046
In PHP typically variables that have not been set or that have been unset are considered null
. The meaning of null
is "no value". There is a distinct difference between "no value" and a value left blank. For instance, if a user submitted a form with foo=&bar=baz
, $_GET['foo']
is set to the value of empty string ""
, which is distinctly different from null
which would be the value for any key other than 'foo'
and 'bar'
.
That all being said, you can find out if a variable was never set or unset
, although they will always evaluate to true
with is_null
(is_null
is the negative of isset
with the exception that it will throw notices if the value was never set).
One way is if you have the variable in an array of some sort:
echo array_key_exists( $variableName, $theArray ) ? 'variable was set, possibly to null' : 'variable was never set';
If you need to check a global variable, use the $GLOBALS
array:
echo array_key_exists( $variableName, $GLOBALS ) ? 'variable exists in global scope' : 'this global variable doesn\'t exist';
The alternative method I've come up with for figuring out whether the variable was set is a bit more involved, and really unnecessary unless this is a feature that you absolutely have to have (in which case you should be able to build it without too much difficulty).
It relies on the fact that is_null
triggers a notice when a variable hasn't been set. Add an error handler that converts errors
into Exceptions
, and use a try...catch...
block to catch the exception that's thrown and set a flag in the catch
statement. Just after the catch
block execute your code that relies on this feature.
It's a dirty-nasty-hack if you ask me, and completely unnecessary, as null
should be considered the same as an unset
variable.
Upvotes: 2
Reputation: 164740
You can't wrap this kind of logic in a function or method as any variable defined in a function signature will be implicitly "set". Try something like this (contains code smell)
function exception_error_handler($errno, $errstr, $errfile, $errline ) {
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
error_reporting(E_ALL);
set_error_handler("exception_error_handler");
try {
if (null === $var) {
// null your variable is, hmmm
}
} catch (ErrorException $e) {
// variable is undefined
}
Upvotes: 2
Reputation: 13117
This only works with globally defined variables. Because of scoping it won't work with local variables in functions or with class properties, but of course it's only one line so you could just copy it into a function.
function isNullOrUndefined($variable_name) {
global $$variable_name;
if (!isset($$variable_name) || is_null($$variable_name)) {
return true;
}
return false;
}
$foo = "foo";
$bar = null;
isNullOrUndefined("foo") //false
isNullOrUndefined("bar") //true
isNullOrUndefined("baz") //true
Upvotes: -1