Wednesday, December 03, 2008

PHP Mystery Solved: @ notation not working

The "@" notation in PHP is both powerful and dangerous. It allows you to temporarily ignore the error from a command.

It's what allows you to say:

  @session_start();

And not have to worry that an error has been raised because the session has been started.

Strangely, when I put my own error handler in place, this notation stopped working. That is, my error handler would be invoked with a E_WARNING in the above code.

I finally got this one figured out today. And of course, it's even fairly sensible. A commenter on the PHP docs explained it well:

I was confused as to what the @ symbol actually does, and after a few experiments have concluded the following:

* the error handler that is set gets called regardless of what level the error reporting is set on, or whether the statement is preceeded with @

* it is up to the error handler to impart some meaning on the different error levels. You could make your custom error handler echo all errors, even if error reporting is set to NONE.

* so what does the @ operator do? It temporarily sets the error reporting level to 0 for that line. If that line triggers an error, the error handler will still be called, but it will be called with an error level of 0

I updated my error handler from saying:

 function smart_error_handler($errno, $errmsg, $filename, $linenum, $vars) {
   // echo stuff to the screen
   // or send e-mail
 }

 function smart_error_handler($errno, $errmsg, $filename, $linenum, $vars) {
   // we've been asked not to report errors, so we'll listen.
   if(error_reporting() == 0) {
     return true;
   }

   // echo stuff to the screen
   // or send e-mail
 }

The condition above checks to see if the @ notation is in effect, and if it is, it quietly ignores the error.

Not only does this make sense, but it's also a more powerful implementation than if the error handler wasn't invoked during an @ function call.

No comments:

Post a Comment