Weak typing in PHP: why use isset at all?

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?


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.
}

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!