tags:

views:

1554

answers:

10

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?

+4  A: 

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);
Triptych
Agreed. What configuration attributes could cause it to break?
Yar
I amended my code to show them
Triptych
It doesn't break anything, but will throw an E_NOTICE type error (doesn't stop script execution).
Eran Galperin
Thanks Triptych for your answer and for updating it. It's a good point, although I think most production servers are actually less strict with error reporting.
Yar
+3  A: 

Because the former could also check for true/false, which you may or may not want.

gms8994
+2  A: 

Because the first produces a warning, and will also return true if $tx === false, which is not the same as not defined

Mikeage
Good point. +1. See comments of http://stackoverflow.com/questions/487737. 14 down, 1 to go (1 per day) – VonC
VonC
+3  A: 

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.

Eran Galperin
Empty arrays!? Okay, I didn't contemplate any of this stuff. Thanks for the answer!
Yar
"exists at all" is not right, as chazomaticus points out: variables may be set to null, so they exist...
Yar
isset returns true for null but set variables. returns false only for variables that are not set
Eran Galperin
A: 

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;
        }
    }
?>
macinjosh
+17  A: 
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.

sirlancelot
unset will never throw a notice or warning
I.devries
Oops, I meant that if you later run `if ($tx)` on the variable it will throw the warning.
sirlancelot
A: 

Turn on ESTRICT error reporting and you will quickly use the latter.

+4  A: 

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.
}
Eli
This answer is huge and really helpful for people who want to understand the differences. Thanks!
Yar
But on later analysis, you're only considering the simple case that the variable hasn't been set by the PHP Processor (on a GET) or that you haven't used it as a user. But objects can be null, functions can return null, etc., as chazomaticus points out... Now if I could mark two answers as best...
Yar
Hey, good point. I had forgotten about that.
Eli
Updated - does anyone think the wording is a bit funny though?
Eli
A: 

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.

Yar
+2  A: 

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!

chazomaticus
whose answer would you add that caveat to? Don't most of the answers mention that already?
Yar
Eli's and Eran Galperin's, specifically. Eli: "If the $condition variable EXISTS, isset() is true, regardless of the value." Except when the value is NULL. Eran Galperin: "The second check (isset()) tests whether the variable exists at all." So long as the variable's value isn't NULL.
chazomaticus