PhpRiot
News Archive
PhpRiot Newsletter
Your Email Address:

More information

Tracking PHP errors

Note: This article was originally published at Planet PHP on 28 November 2010.
Planet PHP

track_errors provides the means to catch an error message emitted from PHP. It's something I like to use during the development of various applications, or to get a handle on legacy code. Here are a few examples why!

For example

Imagine the following remote HTTP call:

$response = file_get_contents('http://example.org/');

So whenever this call fails, it will return false and also emit an error message:

Warning: file_get_contents(http://example.org): failed to open stream: could not connect to host in /example.php on line 2

Some people use @ to suppress this error message - an absolute no-go for reasons such as:

  • it just became impossible to know why the call failed
  • @ at runtime is an expensive operation for the PHP parser

The advanced PHP web kiddo knows to always display_errors = Off (e.g. in php.ini or through ini_set()) in order to shield the visitor of their application from these nasty messages. And maybe they even know how to log the error - somewhere.

But whenever an error is logged to a log file somewhere, it also means it's buried. Sometimes these error logs are too far away and often they get overlooked. If you happen to centralize and actually analyze your logfiles, I salute you!

So how do you use PHP's very useful and informative error message to debug this runtime error?

track_errors to the rescue.

track_errors is a PHP runtime setting.

To enable it:

; php.ini track_errors = On

Or:

ini_set('track_errors', 1);

And this allows you to do the following:

$response = file_get_contents('http://example.org'); if ($response === false) { throw new RuntimeException("Could not open example.org: {$GLOBALS['php_errormsg']}"); }

The last error message is always populated in the global variable $php_errormsg.

You want more?

I also recently used the same technique to implement error checking into a legacy application. I basically did the following:

// footer.php ;-) if (isset($GLOBALS['php_errormsg']) & !empty($GLOBALS['php_errormsg']) && $user-isAdmin()) { echo $GLOBALS['php_errormsg']; }

Trade-offs

As useful as this can be, there are a number of trade-offs. I suggest you use it wisely.

  • $php_errormsg is a global variable [yuck]
  • many extensions provide build in ways to catch errors
  • ini_set() calls at runtime are expensive

Fin

That's all, quick and (very) dirty.