Five reasons why the PHP silence operator @ should be avoided
phpvikinger.org
phpvikinger.org
Can't make this stuff up.
I can't think of another way to do it that wouldn't effectively reduce to this anyway.
Like the fact that the language's grammar is used to do primitive type checking, meaning some combinations of accessors cause errors.
Or the fact the mail sending function doesn't work if one of the lines in the email begins with a period, but only if you're on Windows.
That's one of the many problems with PHP's underlying design philosopy: instead of providing a higher-level interface that stays consistent across platforms, it exposes low-level OS gunk and gotchas through its thin wrappers on low-level-ish functions. I put together phpbestpractices.org a few months ago in an attempt to document some of those common gotchas and provide sane alternatives.
Except they're not really that thin.
>in Windows it wraps the local mail program which seems to have a gotcha with periods
Nope, in Windows it implements the SMTP protocol, on UNIX it runs sendmail.
>instead of providing a higher-level interface that stays consistent across platforms, it exposes low-level OS gunk and gotchas through its thin wrappers on low-level-ish functions.
Except it doesn't. There's quite a few things that are named like OS functions, but are implemented internally. For example, all the C stdlib-like string functions.
Also, I wouldn't be worried about one lookup. I'm pretty sure everything in PHP is in a hash map.
The opcode examination is particularly damning.
I would like to see what PHP 5.4 generates though, the changelog states
- Improved Zend Engine, performance tweaks and optimizations: (Dmitry)
Improved performance of @ (silence) operator
Aha! Found the revision:
http://svn.php.net/viewvc?view=revision&revision=302442I frequently use file_get_contents to retrieve data stored on external servers. If there is a network error or the external service goes down temporarily, it will trigger an error. I don't want my log files flooded with transient error messages that are outside of my control. Instead, I just want it to try again. @ makes this possible.
http://php.net/manual/en/function.parse-url.php
5.3.3 Removed the E_WARNING that was emitted when URL parsing failed.
You might be developing an application that functions in some P2P type fashion or is specifically intended to be used in situations where network access will be intermittent (on a boat perhaps?).
In such a case a mysql_connect call may have a high chance of failing and your application is designed in such a way as to assume that this is likely (i.e working with the return code). In such a case failing the connection is not an error but expected behaviour.
I find it hard to believe that this is actually considered acceptable.
My point is rather that there may certainly be applications where this is not the case.
This is an area where exceptions are better than dumb warnings.
Maybe the solution is to use php 5.4 if it makes better silence code but I am having a hard time letting go of suhosin.
$x = @$f["x"] is right place to use it.
$x = @custom_func() - is a disaster, do not do it
No, it's not. There's built-in methods for that: isset() and empty().
if(function_exists(custom_func) { $x = @custom_func(); }
if((!isset($x)) || (empty($x))) { echo('Custom Error'); } else { //Do the work }
This may be considered verbose, but can be useful if custom or "sometimes" installed libraries are involved
http://php.net/manual/en/function.call-user-func.php
Why would you prepend @ to your function call?
> if((!isset($x)) || (empty($x))) { echo('Custom Error'); } else { //Do the work }
You're duplicating your efforts. empty() takes into account if a variable or key has been initialized, and also if it has a non-false value. isset() only checks if the variable/key has been intialized and nothing else.