Silence of the LAMPs

Avatar von Martin Brotzeller


(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.

In eigener Sache …

Mit WebAssembly die Kosten für die Wartung Deiner Cloud-Anwendung sparen und die Wirtschaftlichkeit und Effizienz des Unternehmens steigern?

Am 26. September 2024 um 11:30 Uhr bieten Dir unsere Experten einen tiefen Einblick in ein spannendes R&D-Projekt.

Melde Dich jetzt kostenlos an!

Avatar von Martin Brotzeller

Kommentare

5 Antworten zu „Silence of the LAMPs“

  1. There is also a big performance hit when using @:

    http://hancic.info/at-operator-is-slow/

  2. Related reads: http://derickrethans.nl/five_reasons_why_the_shutop_operator_@_should_be_avoided.php
    Also, scream is obsolete… the functionality also made its way into Xdebug (2.1).

  3. Aside from being slow, using the ‚@‘ operator in place of appropriate checks and balances isn’t exactly professional. o_O

  4. All valid comments and good article.

    Maybe with time people will finally stop using it whenever they get warnings and they just start fixing stuff ;-)

    PHP movement against @ operator! :- )

    Art

  5. I don’t think it’s really obsolete, as not everyone uses Xdebug – Although that’s possible, it’s still way easier to install the Zend Debugger in ZS for Eclipse.

    About the performance issue – since i didn’t put the @ where i found it, it was not my decision to use it in the first place. I’m thankful for any hints on how to glue those two autoload mechanisms together without the operator. It’s always a hassle to upgrade frameworks when you have to do substantial modifications to fit it to your environment.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert


Für das Handling unseres Newsletters nutzen wir den Dienst HubSpot. Mehr Informationen, insbesondere auch zu Deinem Widerrufsrecht, kannst Du jederzeit unserer Datenschutzerklärung entnehmen.