Why do many PHP Devs hate using isset() and/or any of PHP's similarly defensive functions like empty()?

softwareengineering.stackexchange https://softwareengineering.stackexchange.com/questions/20080

  •  22-10-2019
  •  | 
  •  

Question

Over on stackoverflow, I see this issue crop up all the time:

Even Pekka (who offers a lot of solid PHP advice) has bumped against the dreaded E_NOTICE monster and hoped for a better solution than using isset(): isset() and empty() make code ugly

Personally, I use isset() and empty() in many places to manage the flow of my applications. For example:

public function do_something($optional_parameter = NULL) {
    if (!empty($optional_parameter)) {
        // do optional stuff with the contents of $optional_parameter
    }
    // do mandatory stuff
}  

Even a simple snippet like this:

if (!isset($_REQUEST['form_var'])) {
    // something's missing, do something about it.
}

seems very logical to me. It doesn't look like bloat, it looks like stable code. But a lot of developers fire up their applications with E_NOTICE's enabled, discover a lot of frustrating "uninitialized array index" notices, and then grimace at the prospect of checking for defined variables and "littering" their code with isset().

I assume other languages handle things differently. Speaking from experience, JavaScript isn't as polite as PHP. An undefined variable will typically halt the execution of the script. Also, (speaking from inexperience) I'm sure languages like C/C++ would simply refuse to compile.

So, are PHP devs just lazy? (not talking about you, Pekka, I know you were refactoring an old application.) Or do other languages handle undefined variables more gracefully than requiring the programmer to first check if they are defined?

(I know there are other E_NOTICE messages besides undefined variables, but those seem to be the ones that cause the most chagrin)

Addendum
From the answers so far, I'm not the only one who thinks isset() is not code bloat. So, I'm wondering now, are there issues with programmers in other languages that echo this one? Or is this solely a PHP culture issue?

Was it helpful?

Solution

I code to E_STRICT and nothing else.

Using empty and isset checks does not make your code ugly, it makes your code more verbose. In my mind what is the absolute worst thing that can happen from using them? I type a few more characters.

Verses the consequences of not using them, at the very least warnings.

OTHER TIPS

I think the notices on unknown elements are a design mistake in PHP. I'm not sure it's possible to fix the mistake now, but it produces a lot of boilerplate code like if(isset($foo['abc']) && $foo['abc'] == '123') - this code should not have isset, since the intent is to check if there's '123' in certain place of $foo and if there's nothing there it's definitely not '123'. The only reason you have to write twice as much code there is because of this unfortunate design mistake in PHP. And notices are very expensive in PHP, unfortunately, so just disabling them is not an option for the code where performance is a concern.

So yes, it does make the code ugly IMHO and it does annoy me. And it's not because of lack of experience - I use PHP since 1998 and I remember when there was .php3 extension and it meant "it's not PHP 2". Maybe I am lazy :) But laziness - at least certain type of it - is a virtue for a programmer.

On the other hand, valid use of isset and empty - just like ones in the original post - are fine. I just think PHP is over-zealous about warnings in places where isset/empty are not really needed.

I believe PHP, as a free language, that is interpreted and used on the web, has a very high proportion of non-professional, untrained coders who are not fully aware of why they should code defensively and just see the warnings as another unnecessary error.

I hear these points from junior developers and self-taught script-coders all the time:

  • Why initialise a variable if it will come in to existence anyway?
  • Why check if something exists before we use it, undefined equates to false anyway?
  • If I prefix with @ it fixes my code, why complicate things?

If they have never experienced a strongly-typed language, or experienced the pitfalls of undeclared/uninstantiated variables, then they take some convincing. I find they usually give in once they have experienced the pleasure of debugging code for an hour or so to find it was a typo in a variable name causing the trouble.

The other strong factor is PHP's use in the web industry, which tends to be far more concerned with throughput than safety and code quality.

Yes, they are lazy. A lot of them anyway...

Unfortunately the mentality of many PHP coders is "There is no point coding defensively if you can get the same end result quicker by relying on the language to handle errors caused by missing variables etc etc." I know, I've worked with several of them.

They tend to also be the ones who mysteriously head for an early lunch when their lack of correct error handling and reporting takes out the live servers for several hours...

I try to avoid the use of isset() and empty() by avoiding the use of arrays as data transfer objects. Create a class that can be configured to accept a limited set of properties with sane defaults and validate input to those properties. It can even implement the ArrayAccess interface so you can use it like an array. This also allows you to use type hinting in your method signatures to catch errors when someone attempts to pass the wrong type of entity to your method.

One of the questioned questions is mine, so let me reiterate.

Many developers mistake the presence of lot of isset() as quality sign. It gives an appearance of reliability and some people think of it even as security feature.

But you have to take into account that PHP is not a compiled language. It's a scripting language with a dynamic type system. E_NOTICE errors are only errors by name. And if lots of isset are used with the sole intention of suppressing the notices, then you are actually just coding against the language.

So, are PHP devs just lazy?

That is indeed the case if you see an abundance of notices and warnings thrown. Lot's of newbies don't care about notices, and it's usually the result of a completely disabled error_reporting(0).

You are however mistaken that other developers didn't recognize E_NOTICEs just because they weren't @ or isset-suppressed. At least that was my intention behind the retaining notices question. They aren't something to get rid of, but occasionally important debug info.

Like all generalizations, the inconsiderate use of isset doesn't lead to optimal code. It's important to differentiate where isset and empty are necessary and where they are syntactic salt.

Or is this solely a PHP culture issue?

No, undefined variable "errors" are not a PHP problem alone. Bash, TCL and Perl or JavaScript allow the use of undefined variables. This immanent language feature isn't seen as defect there however. There are similar language constructs to check for undefined values. However they aren't as constantly used as in PHP, due to undef values not being mischaracterized as "error".

Interesting. I hardly ever use isset(). My PHP code is rarely in a state where I dont know if a variable has been set in the first place. Every GET or POST variable used is accessed via a function that will provide it a default if it doesnt exist. Default values in function calls are typically explicitly set to 0 or empty strings.

I use isset and empty plenty. But mostly it's places that you mention, like $_REQUEST processing, in case anyone's been messing with the parameters. In cases where I have control over all the variables flying around, I find that I usually don't need them.

I dont like using isset, but if there is masses of code done by another, then it can be a saving grace. I wrote the wee code below to help with this problem, instead of using isset() isseter($a,$b) will return $b if $a is not defined or empty, or the function returns a null. Any improvements, welcome:

//returns var or NULL (if undefined)
//$reserve optional second value is returned as $default if undefined
function isseter(&$default,&$reserve=NULL)
{
$default = isset($default) ? $default : NULL;
$reserve = isset($reserve) ? $reserve : NULL;
if ((!$default) && ($reserve)) $default=$reserve;
return $default;
}
Licensed under: CC-BY-SA with attribution
scroll top