From b1b8fc0d4a479e022c0142f50f0fdbd2dfbfb92e Mon Sep 17 00:00:00 2001 From: Alan Storm Date: Tue, 18 Feb 2014 14:08:42 -0800 Subject: [PATCH] Rewrite to remove inaccurate @ logging text. --- _posts/08-02-01-Errors.md | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/_posts/08-02-01-Errors.md b/_posts/08-02-01-Errors.md index 1410529..88c0cac 100644 --- a/_posts/08-02-01-Errors.md +++ b/_posts/08-02-01-Errors.md @@ -59,39 +59,33 @@ You can also control whether or not errors are displayed to the screen (good for ### Inline Error Suppression -You can also suppress specific errors from being displayed using the Error Control Operator `@`. You simply put -this operator at the beginning an expression, and any error that would be caused as a direct result of the specific -expression will be silenced. +You can also tell PHP to suppress specific errors with the Error Control Operator `@`. You put +this operator at the beginning of an expression, and any error that's a direct result of the expression is silenced. {% highlight php %} echo @$foo['bar']; {% endhighlight %} This will output `$foo['bar']` if it exists, but will simply return a null and print nothing if the variable `$foo` or -`'bar'` key does not exist. +`'bar'` key does not exist. Without the error control operator, this expression could create a `PHP Notice: Undefined variable: foo` or `PHP Notice: Undefined index: bar` error. -This might seem like a good idea, but due to the way PHP actually handles `@` it is incredibly unperformant, and has the -unexpected effect of still actually logging the error anyway. If you have this code in a loop that runs 100 times in an -instance, and you run that 1 million times, then you've got 100 million lines in your logs. +This might seem like a good idea, but there are a few undesirable tradeoffs. PHP handles expressions using an `@` in a less performant way than expressions without an `@`. Premature optimization may be the root of all programming arguments, but if performance is particularly important for your application/library it's important to understand the error control operator's performance implications. -Instead, use the following: +Secondly, the error control operator **completely** swallows the error. The error is not displayed, and the error is not send to the error log. Also, stock/production PHP systems have no way to turn off the error control operator. While you may be correct that the error you're seeing is harmless, a different, less harmless error will be just as silent. + +If there's a way to avoid the error suppression operator, you should consider it. For example, our code above could be rewritten like this {% highlight php %} echo isset($foo['bar']) ? $foo['bar'] : ''; {% endhighlight %} -This will be much quicker, and save filling up your logs with junk. [SitePoint] go a step further and say you should -[never suppress notices] with `@`. - One instance where error suppression might make sense is where `fopen()` fails to find a file to load. You could check -for existence of the file before you try to load it, but if the file is deleted after the check and before the `fopen()` +for the existence of the file before you try to load it, but if the file is deleted after the check and before the `fopen()` (which might sound impossible, but it can happen) then `fopen()` will return false _and_ throw an error. This is potentially something PHP should resolve, but is one case where error suppression might seem like the only valid solution. -In a stock PHP system, the behavior of the error control operator is irreversible. There are no configuration settings which allow a suppressed error to be temporarily un-suppressed. - -However, [xDebug] has an `xdebug.scream` ini setting which will disable the error control operator. You can set this via your `php.ini` file with the following. +Earlier we mentioned there's no way in a stock PHP system to turn off the error control operator. However, [xDebug] has an `xdebug.scream` ini setting which will disable the error control operator. You can set this via your `php.ini` file with the following. xdebug.scream = On @@ -108,7 +102,6 @@ This is most useful when you're debugging code and suspect an informative error * [Error Control Operators](http://php.net/manual/en/language.operators.errorcontrol.php) * [SitePoint](http://www.sitepoint.com/) -* [never suppress notices](http://www.sitepoint.com/why-suppressing-notices-is-wrong/) * [xDebug](http://xdebug.org/docs/basic) * [Scream](http://www.php.net/manual/en/book.scream.php)