It seems like my code works to check for null if I do
if ($tx)
or
if (isset($tx))
why would I do the second one when it's harder to write?
It seems like my code works to check for null if I do
if ($tx)
or
if (isset($tx))
why would I do the second one when it's harder to write?
The first one only works depending on how your server is configured. On many production servers, it will break.
Use isset()
and be merry.
Or, try your code with the following at the top of the PHP source and watch it break:
ini_set('display_errors', 1);
error_reporting(E_ALL);
Because the former could also check for true/false, which you may or may not want.
Because the first produces a warning, and will also return true if $tx === false, which is not the same as not defined
Put simply, those comparison are not the same. The first will cast the variable to a boolean, which will fail the check on empty arrays, non-numeric strings and other checks, in which the variable is definitely set. The second check (isset()) tests whether the variable exists at all.
I would never perform the first check (boolean cast) without checking the type of the variable as well.
Not to mention, the first check will throw an E_NOTICE, and I always run with at the maximum error reporting level.
It also important to note that a string in PHP could be set but empty. So the isset would return true even though there is nothing in the string, to prevent this I use a function something like this to replace isset:
<?php
function exists($var) {
if (isset($var) && $var != "") {
return true;
} else {
return false;
}
}
?>
if ($tx)
This code will evaluate to false for any of the following conditions:
unset($tx); // not set, will also produce E_WARNING
$tx = null;
$tx = 0;
$tx = '0';
$tx = false;
$tx = array();
The code below will only evaluate to false under the following conditions:
if (isset($tx))
// False under following conditions:
unset($tx); // not set, no warning produced
$tx = null;
For some people, typing is very important. However, PHP by design is very flexible with variable types. That is why the Variable Handling Functions have been created.
isset() has nothing to do with TYPE or VALUE - only with EXISTENCE.
if ($condition)... will evaluate the VALUE OF THE VARIABLE as a boolean value.
if ( isset($condition) )... will evaluate the EXISTENCE OF THE VARIABLE VALUE as boolean.
isset() can be false for two reasons.
Firstly, because the variable is not set, and so has no value.
Secondly, because a variable is NULL, which means "unknown value" and can't be considered set because it includes "no value" and because so many people use $v = null to mean the same thing as unset($v).
(Remember, if you specifically want to check for null, use is_null().)
isset() is usually used to check an external variable that may or may not exist.
For example, if you have a page called page.php, that has this:
ini_set('display_errors', 1);
error_reporting(E_ALL);
if ( $_GET["val"] ) {
// Do Something
} else {
// Do Nothing
}
it will work ok for any of these URLS:
http://www.example.com/page.php?val=true // Something will be done.
http://www.example.com/page.php?val=monkey // Something will be done.
http://www.example.com/page.php?val=false // Nothing will be done.
http://www.example.com/page.php?val=0// Nothing will be done.
However, you will receive an error for this URL:
http://www.example.com/page.php
because there is no 'val' argument in the URL, so there is no 'val' index in the $_GET array.
The correct way to do this is like:
if ( isset($_GET["val"]) ) {
if ( $_GET["val"] ) {
// Do Something
} else {
// Do Nothing
}
} else {
// $_GET["value"] variable doesn't exist. It is neither true, nor false, nor null (unknown value), but would cause an error if evaluated as boolean.
}
Though there are shortcuts for this.
You can check for a combination of existence and certain Boolean conditions with empty(),
if ( !empty($_GET["val"]) ) {
// Do someting if the val is both set and not empty
// See http://php.net/empty for details on what is considered empty
// Note that null is considered empty.
}
or
if ( isset($_GET["val"]) and $_GET["val"] ) {
// Do something if $_GET is set and evaluates to true.
// See php.net logical operators page for precedence details,
// but the second conditional will never be checked (and therefor
// cause no error) if the isset returns false.
}
These two are quite different, as every single answer has pointed out. If you do not use isset, many things will evaluate to false, especially arrays, values of false, numeric values of 0 (and others), etc. True that.
It seems strange to me that everyone is so quick to defend correct programming in PHP. If I want to do correct programming, I've got tons of statically-typed, strongly-typed languages to do it with. It seems to me that one advantage to PHP is that I don't have to think about types that much. Sure, there are cases where
if ($tx)
evaluates to false when it in fact does have a value, but if you want to check if it's a Transaction Object or not, it either works or it doesn't. It turns out that, with the Doctrine framework, this code
if (isset($tx))
always evaluates to true after grabbing the first object of a query. I instead have to say
if ($tx instanceof PurchaseRecord)
So my point is that in PHP, you know what you're testing for! For instance, if it's a parameter from a GET request, it will either be null, empty, or have a value. You must handle these three cases. Or two cases, or whatever number of cases you have in your particular code. Once you have, if it works on your development server and it works on your production server, maybe you can say that it works and get on with your life?
(In Java or C#, it has to compile and then run without throwing Exceptions. Most NullPointer exceptions in Java actually get thrown with no problems being caused: Java APIs cannot possibly check for all nulls in code because it's impossible, and also because it's no problem. If it compiles and works when it's supposed to, you know your code is okay. Then later you can worry about throwing more correct Exceptions.)
If at all points you have to know what the underlying types of your code in PHP, why not code using types in the first place? Or more to the point, why not take advantage of the looseness of PHP and code with code that runs.
I want to point out that everyone's reponse I've read here should have one caveat added:
"isset() will return FALSE if testing a variable that has been set to NULL" (php.net/isset).
This means that in some cases, like checking for a GET or POST parameter, using isset() is enough to tell if the variable is set (because it will either be a string, or it won't be set). However, in cases where NULL is a possible value for a variable, which is fairly common when you get into objects and more complex applications, isset() leaves you high and dry.
For example (tested with PHP 5.2.6 with Suhosin-Patch 0.9.6.2 (cli) (built: Aug 17 2008 09:05:31)):
<?php
$a = '';
$b = NULL;
var_dump(isset($a));
var_dump(isset($b));
var_dump(isset($c));
outputs:
bool(true)
bool(false)
bool(false)
Thanks, PHP!