Is there a good way to differentiate between variables or array indices set to NULL versus variable or array indices that haven't actually been set?

The only way I can see is to test if the variable or array index exists:

if ( array_key_exists( 'indexBeingTested', $array ) )
    {
    echo is_null( $array['indexBeingTested'] ) ? "is set and is NULL" : "is set and is NOT NULL";
    }
else
    {
    echo "Never been set";
    }

// or for variables:
$allVars = get_defined_vars(); // or use $GLOBALS
if ( array_key_exists( 'variableName', $allVars ) )
    {
    echo is_null( $variableName ) ? "is set and is NULL" : "is set and is NOT NULL";
    }
else
    {
    echo "Never been set";
    }

Did I miss something, or is this the only way to distinguish between not set and NULL?

    Hm..

    As far as I can tell NULL and not set are just about the same.

    Out of curiosity.. Why would you want to differentiate?

      Right. They're the same except for the fact that a variable or index can be non-existent before it can be set to NULL. Those are two different states. They both test out the same conditionally in PHP, but the differences in those two states is undeniable. In one case you have a variable or index that hasn't entered your scripts execution, on the other hand you have a variable or index that has been executed, but has been given or deemed to be a NULL value.

      So if you rely on a script that may or may not set a variable or array index (which would indicate whether or not that variable or index was in fact processed by that script), then testing for the difference between never set and set but NULL could be valuable. In my situation, it is a valuable bit of knowledge.

      I think this distinction is more important and probably more relevant for array indices, but I threw in the variable condition just to be thorough (even though you end up testing the existence of variables in the same exact manner as the array indices).

        Oh, c'mon! isset returns false for both unbound variables and for NULL variables. It does not differentiate between "never been set" and "set but NULL"

          Hi Zeb,

          To avoid this sort of trouble, I usually have a specific value set for a nodata / not set value. e.g.: I never use -2 for anything, except in variable checking. Whenever I want a var ignored, I set it to -2, for which you can easily check.

          ?

            That's true, I could do that. It is easy to employ that sort of solution when you have a script serving a very specific purpose; but in terms of compatibility, expandability, and scalability, choosing something like that could be detrimental. The project I'm working on needs to have all those features. Where this need exists is in the core script into which many modules and extensions connect.

            I was just wondering if there was any built in way of checking this.

            mrhappiness: I just re-read my last post and realized that my tone was slightly harsh. That wasn't my intent. It was still early for me...

              zeb wrote:

              mrhappiness: I just re-read my last post and realized that my tone was slightly harsh. That wasn't my intent. It was still early for me...

              /me bows and lifts hat:
              I wondered about that post.. Takes a big man to get back to a shortened out fuse 😉

              I agree with the scalability problems & risks. I am not sure whether you can get it to work though. I have found some hickups in variable treatments in PhP. But maybe.. Someone comes with a good solution.

              Good luck 🙁

              J.

                It does not differentiate between "never been set" and "set but NULL"

                That's because NULL also means "never been set". Read the PHP Manual on NULL for more information.

                  Thanks leatherback.

                    laserlight wrote:

                    That's because NULL also means "never been set". Read the PHP Manual on NULL for more information.

                    Not exactly, they say

                    A variable is considered to be NULL if

                    • it has been assigned the constant NULL.

                    • it has not been set to any value yet.

                    • it has been unset().

                    they use the phrase "considered to be NULL if". NULL can't mean "never been set" if you can set it to NULL in the first place. It has been set. It's a contradiction. Consider too the fact that you can pull a NULL value from a database. from the manual page for mysql_fetch_row(): "Note: This function sets NULL fields to PHP NULL value." The resulting array contains an index that does exist and has been set to NULL. That's different from that index "never being set". That index now exists to inform you that there is a value in the database that is NULL. So the fact that it exists is important which necessitates the need to differentiate between an existing variable/index and one that in fact isn't there.

                      I'm not saying that never-been-set variables and indices shouldn't be considered NULL. In most circumstances, it's enough to test a variable existence with isset or is_null. I am saying that there are times when it's helpful to know if a variable/index exists (has been executed and bound to something) versus simply being set to NULL.

                        Hi Zeb,

                        As I posted earlier.. PhP is not as strickt as most languages. So.. In most languages you can initiate a var, by saying: varname = vartype. In PhP thsi distinction is not made. So.. NULL == unset() = not set yet

                          they use the phrase "considered to be NULL if". NULL can't mean "never been set" if you can set it to NULL in the first place. It has been set. It's a contradiction.

                          I disagree. Here the concept of NULL means "no value". If a variable is not set, or has been unset, it has no value. Likewise, if a variable is set to NULL, it has no value.

                          The resulting array contains an index that does exist and has been set to NULL. That's different from that index "never being set". That index now exists to inform you that there is a value in the database that is NULL.

                          This fits in with a concept of null values in a database. The field has no (or an unknown) value, but it exists. You can check for the presence of the field (as represented by the array element) with [man]array_key_exists/man.

                          EDIT:
                          You did that in your example, and as far as I can tell, it should be the way to go for what you want to do.

                            I'm not really talking about "no value", but that's the problem with PHP, it groups all these cases:
                            • variable has no value, but exists
                            • variable use to have values, but no longer has one
                            • variable? what variable? it never existed
                            • variable use to exist, but has been released from existence (unset)
                            into one type without giving you the way to distinguish between them.

                            zeb wrote:

                            They're the same except for the fact that a variable or index can be non-existent before it can be set to NULL. Those are two different states. They both test out the same conditionally in PHP, but the differences in those two states is undeniable.

                            Is this not undeniable?

                              Is this not undeniable?

                              I agree, but I think you solved your problem in your initial example - by the use of array_key_exists(), so you are right to conclude that "this the only way to distinguish between not set and NULL".

                              For the case of scalars (and even of array elements, for the general case), I would question if there is a need to be uncertain about what variables should exist (e.g. potential variable poisoning). leatherback's suggestion holds here, though in actual use it depends on context, e.g. the use of false may be more suitable.

                                You're right. In a properly coded script, you should always know what variables should exist, though array indices are a bit more fluid because they often involve iteration. The deeper your arrays and the more complex your logic gets, the higher likelihood of overlooking something. I'm not sure yet if my need will only end up being for debugging purposes or if it will end up being permanent. My script has almost become more than I can manage at the moment, which is why I'm trying to rewrite and streamline much of it. There may exist in the future the possibility of having third party developers write modules for use with my script. Doing this further opens up the possibility of corrupt data or poorly written modules. I'm just trying to have my scripts use formative or otherwise safe error handling in case something does go wrong.

                                Thanks for your advice you two. I'll go on using array_key_exists() until I can convince one of the PHP developers that this distinction may in fact be helpful to others. 😉

                                  Write a Reply...