(based on a true story)
A well-known but discouraged operator in PHP is the silence operator @, that supresses any output,
that a particular command may yield. Read on to find out how you should not use it.
The silence operator exists to give programmers an easy way to suppress messages
when a command might fail and the code checks for success itself (i.e. in those cases
that raise errors instead of throwing exceptions). Take fopen() for example, it produces an
E_WARNING when an error occurs. In that case you can put an @ before the function call because you
know what you’re doing. Everyone else who sees the code will probably understand that.
It gets nasty, though, when that happens in parts of the code that are not directly accessible.
Zend Loader, the autoloader from the Zend Framework finds files according to a strict naming scheme,
When a class like „Foo_Controller_Action_Helper“ is to be
loaded, the Zend Loader replaces „_“ with „/“ and checks for illegal characters. After that it
tries to include the file:
public static function loadClass($class, $dirs = null) { ... $file = str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php'; ... self::_securityCheck($file); include_once $file; }
At a site I’m currently working on, the Zend Loader is combined with an older autoload script that
is supposed to find files that don’t follow the naming scheme because they come from older
code. Since the include_once of Zend Loader fails in this case, one developer prepended the line
with an @ to reduce the noise in the errorlog.
The downside of this is, when a file that is found contains errors, those are suppressed too, because
@ simply turns off all error reporting. In combinations with an autoload mechanism, this means a
programmer that relies on the autoloader gets a script that tries to instantiate a class an dies
without any hint on how and where. One might get the impression that PHP somehow dies while trying
to instantiate the class and wonder why not even apache writes something into its errorlog about
a PHP segfault. Only when you manually include the class file before you try to instantiate the class, you get
a hint on what happens. After that it’s easy to find the warning in the php manual that explains
everything:
Warning
Currently the „@“ error-control operator prefix will even disable error reporting for critical
errors that will terminate script execution. Among other things, this means that if you use
„@“ to suppress errors from a certain function and either it isn’t available or has been mistyped,
the script will die right there with no indication as to why.
A helpful hint came from Johannes Schlüter, who recommended
Pecl/Scream
for development systems. Scream completely disables the silence operator. Thus the errorlog probably
contains a bit more noise, but it’s for sure better to filter out unimportant messages
than to have to guess where a script may die.
Schreibe einen Kommentar