You are here

PHP - isset() or null?

Submitted by Peter on Fri, 2012-07-06 22:14

technology:

You can define PHP variables without a value or a default of null. Which technique is best?

Test this common approach for setting static variables in PHP functions.

function cels() {
  static $cels;
  if (!isset($cels)) {
    $cels = new Cels();
  }
  return $cels;
}

Now test this version of the code using null, as recommended by Rasmus Lerdorf, the inventor of PHP.

function cels() {
  static $cels = null;
  if ($cels === null) {
    $cels = new Cels();
  }
  return $cels;
}

Rasmus says the test for null is faster than the test of isset. His recommendation is sufficient reason to look at the difference seriously. The difference would be significant if you had a small loop going through the same code thousands of times in the one Web page request.

The null test does one other good thing. If you use Netbeans to edit code, Netbeans complains about static $cels; having an uninitialised variable. initialised variables are better than uninitialised variables. Defining the variable as null is a good approach for both of the reasons mentioned so far.

Now for the problems.

static $cels = null; will create a problem if $cels can contain null as a valid value. You have to do something completely different to handle a variable where all values are possible, as shown next.

function cels() {
  static $cels = null;
  static $cels_initialised = false;
  if ($cels_initialised === false) {
    $cels = new Cels();
    $cels_initialised = true;
  }
  return $cels;
}

Using $cels_initialised is slower than testing for !isset(). You do gain compatibility with languages that do not have the equivalent to the isset() test. When you are converting from Java and other languages, you may need to allow for the possibility of a conversion from PHP to another language and add extra code to make your tests independent of the language.

Stick to one type

One of the basic rules of programming is to stick to one type for a variable. You reduce the chance of confusion. Using ,code>$cels = null is stupid in open code where other people can write code to access your variable. If the variable is supposed to contain a number as a floating point value. Placing a null in there is guaranteed to make the code blow up at a critical point. if the variable is floating point, use a floating point number. Zero and one are obvious candidates. When the variable is added to things, the initial value of zero will stop the variable from altering anything. if the variable is multiplied against things, as you do with tax, an initial value of one will leave all multiplied values unchanged.

The following example function returns a tax rate returned from somewhere else by function get_tax_rate_from_somewhere(). The result is stored locally for the life of the processing. The initial value is set to one so it does not alter prices when multiplied against a price. The initial value is useless because we always call the function to get a new tax rate. This approach would be more relevant if we were testing the value returned by the function.

function tax_rate() {
  static $tax = 1;
  static $tax_initialised = false;
  if ($tax_initialised === false) {
    $tax = get_tax_rate_from_somewhere();
    $tax_initialised = true;
  }
  return $tax;
}

The following version is expanded to fetch the tax rate once and to ignore the fetched tax rate if the tax is zero. You might get the tax rate from a bank and their system returns zero if the data is not available. in real life, you get all sorts of funny things to put in this type of code. The other system might supply the tax rate as a string containing AU:10%, or some even more complicated format, and have to decode the value.

function tax_rate() {
  static $tax = 1;
  static $tax_initialised = false;
  if ($tax_initialised === false) {
    $new_tax = get_tax_rate_from_somewhere();
    if ($new_tax != 0) {
      $tax = $new_tax;
    }
    $tax_initialised = true;
  }
  return $tax;
}

Conclusion

Testing for a variable as null is is logical for speed and to keep Netbeans happy. Null is often a value value and you have to test something else. Testing isset() is the closest you get in PHP code to what you mean. Using a separate variable is the slowest approach and is sometimes the safest approach.