PHP: Be careful with global constants

Did you know that global constants, when undefined, evaluate to a string containing the constant name? Talk about a mouthful – here’s an example repurposed from the PHP docs:

<?php
define("CONSTANT", "Hello world.");
echo CONSTANT; // outputs "Hello world." 
echo Constant; // outputs "Constant" and issues a notice.
?>

Depending on your programming background, this probably isn’t what you had in mind. Not me at least – all the languages I’ve ever dealt with fail when attempting to evaluate undefined constants.

That means that if you’re not careful, an undefined constant can cause bugs like this:

if ($user_level < ADMIN_LVL) { // Typo! Should be ADMIN_LEVEL
   // always evaluated
}

I’ve also seen permutations of the following:

define('DEBUG_MODE', true);

if (DEBUG) { // Yes, another typo
  // always executed -- aside: should use if_defined
}

There’s a couple defensive measures you can take. One, use an error reporting level of E_STRICT or E_ALL during development, which will emit a warning in the case above—if it’s evaluated. Better yet, stick to class constants. Undefined class constants throw good old fashioned errors, just like Ruby, Python, et al.

class Consts {
  const ADMIN_LEVEL = 5;
}

// Later that day ...

if ($user_level < Consts::ADMIN_LVL) { // Here's that typo again
  // throws an error
}

Failing fast like this could be the difference between having a bug reported to you immediately by your users, or having a bug reported to you 3 months later when errors pop-up in your database. Don’t know you guys, but I’ll take the first one.

Looking back at 2007

As far as accomplishments go, 2007 has been a good year. I joined FreshBooks in April (it’s been great), had my first academic paper published in August, and was chosen to participate in next year’s SXSW Interactive. On top of that, this blog reached 100 readers over the summer – thanks you guys.

Speaking of which, the only real down note is how I’ve labored with this blog these past few months. I’ve had article ideas bouncing around in my head, but the most important step – writing them out – has totally eluded me. So, my first resolution for next year is to rediscover my writing touch and whip this blog back into shape.

My other resolutions? Write more code for the hell of it, build something with merb, and contribute to a proper open source project. I’ve shared plenty of half-baked code here on my blog, but I’d like to get involved with a project with legs – whether I’m writing docs, test cases, or patches, it’s all good. (Looking for help? Drop me a line.)

So here’s to a new year – may it be a good one.