Suppressing PHP errors for fun and profit
Posted on 28/1/09 by Felix Geisendörfer
Update: The conclusions below are wrong, empty() is the best solution to the particular problem, read the follow up post for more information.
As of late I am getting sick of some best practices I have taught myself. Never using the @-error suppressing operator quickly moving to the top of the list.
Before you start crying out loud (I know you will), let me say this: I do not mean to encourage anybody to use the @-operator. Applying the practice herein introduced may result in permanent damage to your coding habits and could serve as a gateway behavior to writing shitty code.
Ok, you have been warned, lets move on. Today I found myself writing the following line of code:
I was basically checking for a sub-key of an element to be true(ish). However, I knew this sub-key may not be included in the array under some circumstances, so a direct check for it could result in a PHP warning.
You can probably feel the pain of conflict here. On one side I want to write very short and expressive code. On the other side I am also trying to follow the so called "best practices". It is impossible.
Of course there is always the option to normalize the array before doing the check:
if ($step['options']['merge']) {
// do stuff
}
This however still adds a basically useless line of code. Plus normalizing a multi-dimensional array like this requires a more sophisticated merging algorithm than PHP provides you with (CakePHP's Set::merge() function provides good multi-dimensional array merging, but that would be throwing even more code and CPU cycles at the problem).
So today I have, for probably first time in years, I wrote the following line of code:
// do stuff
}
It still causes me mild pain to look at. I hope for that to go away soon. But I no longer have the strength to close my eyes to the very true lesson to be learned here: Using the @-operator like this solves more problems for me than it creates.
This may not be true for you. Using the @-operator is 4x slower than solution #1 and 1.3x slower than #2. If you run a loop with 100000 records, this is 150ms wasted (on my laptop, your mileage may vary). However, my scenario is more like running into this 5-10 times for any given request. So we are talking about 0.0015ms here.
It is not like I don't care about my CPU-cycle footprint. The opposite is true. By sparing myself the pain of typing up and maintaing more verbose-than-necessary code I can save millions of CPU cycles elsewhere! I can go and optimize stuff that actually needs to be optimized.
How will you choose?
-- Felix Geisendörfer aka the_undefined
PS: In case you wonder, @-suppressed errors do not show up in any error logs. So no problems with that.
You can skip to the end and add a comment.
How about:
if (!empty($step['options']['merge'])) {
// do stuff
}
Usage of '@' is horrible. It might look okay in this simple case, but a few weeks later you change the code to something like this:
if (@$step['options']['merge'] && really_check_for_merge($step)) {
// do stuff
}
and you will never find a bug in the expression.
use if !empty() no? As it doesnt throw an error if it is not there, but will still tell you if you havea true
if (!empty($step['options']['merge'])) {
// do stuff
}
Thanks guys! I posted a follow up here:
This post is too old. We do not allow comments here anymore in order to fight spam. If you have real feedback or questions for the post, please contact us.
How about?
if (isset($step['options']) && isset($step['options']['merge']) && $step['options']['merge']) {
// do stuff
}