Bad uses of the @ operator
In PHP,@ is called the error suppression operator. It
is sometime a convenient way to tell PHP that it shouldn’t generate a
warning (or a notice) at some piece of code because you know it’s
perfectly correct to ignore that particular warning. I’ve found out that
the @ operator, if overused, can impose an important speed
penalty. Hense, here is a list of things you shouldn’t do with this
operator.
Replacing isset
When you have a variable that you aren’t sure is set, do not use the
error suppression operator to remove the “variable not set” notice, it’s
about 2 times slower than using isset. Example:if (isset($albus)) $albert = $albus;
else $albert = NULL;
is equivalent to:$albert = @$albus;
but while this second form is a nice syntax, it runs about two times
slower. A better solution is to assign the variable by reference, which
will not trigger any notice, like this:$albert =& $albus;
However, using this assign-by-repherence trick may induce unintended
side effects if you were going to modify any of the two variable later.
My rule is to use this trick only in performance-critical areas and
where I’m sure it won’t affect anything.
With the list construct
PHP allow you to assign multiple variables at once from an array using the list construct. The most common case of list is with the explode function which simply split a string in multiple parts. For example:list($a, $b, $c) = explode('/', 'part1/part2/part3');
But often, you cannot be sure that the string you’re “exploding” has
as many parts as you have variables listed. This will result in a PHP
notice which is easily dismissed with the error suppression operator:@list($a, $b, $c) = explode('/', 'part1/part2');
and in this case, the variable $c will be set to NULL. But again, @ is pretty slow. It’s so slow that, for this example at least, I’ve found that it’s faster to use array_pad to fill the array so that it contains enough values like this than to use the error suppression operator:list($a, $b, $c) = array_pad(explode('/', 'part1/part2'), 4, NULL);
That’s getting pretty ridiculous.The best solution I have found is to assign each variable by reference, like this:
$result = explode('/', 'part1/part2');
$a =& $result[0];
$b =& $result[1];
$c =& $result[2];
Since you weren’t going use $result anyway — you were using list
which did not assign the full array to any variable — assignment by
reference shouldn’t cause much trouble. From my testing, this is a
little slower than using list, but still way faster than anything using the error suppression operator.Conclusion
So what is to be remembered from all this? Simply don’t use the error suppression operator with speed-critical code. Writing more code to work around the tricky cases will always be faster.Of course, if you don’t care about notices (most probably because you have set the error level to not include them) you don’t need any of these tips because you don’t need the error suppression operator for variable assignment. But if you’re deploying your software around on servers which do log notices, hopefully this information will be handy. At the very least, it will be for me and my PHP projects.
Notes: All tests were done with PHP 5 with error reporting at
E_ALL. Results may vary with other versions and other settings.
0 comments:
Post a Comment