Saturday, June 21. 2008Notification Free PHP CodingComments
Display comments as
(Linear | Threaded)
agreed, but what do you recommend instead when you cannot set error_reporting or display_errors (e.g. cheap hosting)?
So what do you propose instead of it? Polluting log files with notices? Or, better yet, turning down error reporting level?
How about
$email = @$values['email'] ? "Your comment did not contain a Session-Hash. Comments can only be made on this blog when having cookies enabled! You did not specify the email field! Your comment could not be added because comments for this entry have either been disabled, you entered invalid data, or your comment was caught by anti-spam measurements." And your blog was probably also written by somebody like this.
You mean array_key_exists() I presume? Very slow compared to isset() and empty(). But what we really want is ifsetor().
Perhaps I do not grasp this post entirely, though I really wonder what you did have in mind for a proper solution?
There is a very good reason to write notification free PHP, because it helps you spot programmer error. If you mistype an array key, you'll notice as soon as that code is first executed. With that in mind, if you code is full of false-positive notifications, you'll never see the useful notifications.
Why not just build a data array by merging some default values with the user-provided data? This will ensure that all the necessary data exists with less effort, more readability, and better efficiency.
$defaultValues = array( 'email' => null, 'password' => null, 'firstname' => null, 'secondName' => null ); $data = $values + $defaultValues;
Here is an argument for notification free code:
If you're running a production site and you've written notification free code you can log all notices. Any logged notices means something unexpected happened and it's probably a bug. You then get notification of an unexpected code path on a production site. If you write code expecting notifications you will be unable to detect unexpected notices on production sites because logging would flood you with bogus notices. Writing notification free code is a technique to prevent bugs, not some sick desire to write more code.
I don't see the problem with it pre-defining variables. I don't know about setting them all to null, but I'm a huge fan of setting variable defaults.
If PHP would preset vars to null as they're used, we wouldn't need to do it our selves. I like to keep the notice count to zero. Especially because those notices get in the way when coding in E_STRICT. There's been talk on the internals list about allowing an empty "true" portion of the ternary operator for this exact reason. Would be much cleaner as: $var = array_key_exists('my_var', $_POST) ?: 'var_default'; or even: $var = isset($_POST['var']) ?: 'var_default'; Mark
"If PHP would preset vars to null as they're used, we wouldn't need to do it our selves."
If one of my variables isn't set, that doesn't mean I want it to be NULL, that means I apparently forgot to set it, which is something I want to know about. Defaulting any variable to any value can cause unexpected and undesired behaviour.
I agree for the case you forgot to initialize. But i use un-initialized variables on purpose. Because i know that they are NULL then. Or 0 or and empty string. I appreciate that PHP does it this way and again: There is nothing unexact about it. It is all defined and well tested. This is why i use PHP.
But think of all the code that you will save
http://symfonynerds.com/blog/?p=10
This does make sense: to avoid notice.
I really have to have notice. If you really care about the result you must ensure what values are in your variables.
Well, it is defined that a value will be NULL when uninitialized. If i know that, i can deal with that. Nothing unexact there...
"Solution" to be right, must be complete and precise. If it's not, then you don't get solutions, but only rough estimations. If you believe estimation will be enough, then you need to redefine your problem.
Simple code is good, but if it's to simple, you will start loosing precision and completion of the solution, and that would be application failure, as it will stop fulfilling its function.
i agree absolutely: No solution should be simpler than the problem. But also not more complex. Or even complicated. No rough estimation btw: it is defined that an undefined array element will give you null. You can ask for it or just use that fact for later statements.
That's why I like to stick that kind of data into an object, and provide accessor methods. This prevents you from duplicating the ternary operator all over and still gives you notification-free code without hassle.
Well, IMHO this goes back to the good ol' "PHP is not Java" discussion i guess
I agree that in many cases this is a good solution. But still, i prefer the cool PHP tricks that make everything more solution oriented and less technical...
PHP's built in error handling / reporting is for catching errors in your scripts and their dependencies (db, web service, etc) not errors in user input.
If your script requires certain input then you'd better check or it or else inform the caller of the bad input. Letting php generate a notice does nothing for the caller and only hassles your developers who's time would be better spent tracking down real bugs instead of wading though useless log entries. I really hope this blog post was an attempt to troll . . .
I knew in advance that i would get some comments. But it is not to troll. I really think that coding notice-free takes a lot of advantages of PHP away. You can enable notices if you search for an error and really don't see where it comes from. But notice-free programming adds so much noise to your code that it IMHO does more harm then it helps.
I did a lot of big and serious projects in PHP and i must say the big problems never where trackable by notices but they always resulted from losing overview over the solution...
Your example has nothing to do with E_STRICT compatibility but with your programmer not spotting the pattern. What he/she wanted to do is a get_value()-function:
$value = get_value($values, 'email'); And in general it is a good idea to avoid any warning. Not just because warnings because of someone being lazy hide real errors, but because everytime a warning is triggered it is a hint, that the programmer was too optimistic. Being optimistic is not the best thing, designing for failure is. @Lukas: key_exists() is a completely undocumented alias to array_key_exists(), that's why the code would work. I agree about warnings. But (as you know) i believe that code readability is the best way to ensure quality. The less technical noise is in your code, the better you see the solution and the less errors you make...
Anyways .. using key_exists() is a bad idea. Its much slower compared to isset() and even longer to type. Oh and while we are at it. There is a solution that leads to short code without notices:
http://wiki.php.net/rfc/ifsetor#userland_2
I'm all in favor of notification-free coding.
The verbosity of the example you gave is quite annoying, but using a simple array_merge, as advocated by Antony, makes it both correct, fast and quite readable. Using @ is otoh a sure way to make your code slower and hide a real error every now and then. A very useful php feature, to be used with great care.
There's much to be said on the way how to prevent notices in this case, but in general, notice free programming is a good thing. It not only helps to spot typo's early (as mentioned above), it also helps prevent security issues (undefined variables). In the good old days when register_globals was still on, this was very important.
I don't think it has to do with simplicity, there are simple ways to prevent notices so you can create notice free code without any additional complexity. A coworker showed me though how '@' makes code significantly slower. He's preparing some benchmarks and we'll write a blogpost on it soon. |
Calendar
QuicksearchCategoriesBlog AdministrationTop ReferrersChoose Language |
|||||||||||||||||||||||||||||||||||||||||||||||||


Tracked: Aug 20, 16:23