Unsettling
isset — Determine if a variable is set and is not NULL
We’re not even through the first sentence of this manual page and I am already wondering why we’re conflating two completely different definitions of a variable being “set” in one function. This function simultaneously tests whether the variable name exists and whether the value of the variable is non-null. In my personal opinion, those are two very different questions. I don’t need a special snowflake function to test if the contents of a variable is null, but I do need one to inquire of the runtime if a variable name has been declared. (Insofar as PHP declares anything, which it doesn’t, really.)
Special snowflake functions is kind of the name of the game with PHP, though. We’ll get back to that…
… because isset() isn’t even a function. It’s a godsdammed token. A token. Parsed by the parser. This is like sizeof() in C, except it does run at runtime rather than returning a constant at the parsing stage, unless the PHP parser has solved the halting problem. The documentation calls it a “language construct,” implying, well, I don’t know what that implies, because everything is a language construct. This particular quirk has already been covered in the masterpiece of PHP hate blogging, but it bears some pondering. Note that isset() is documented under the list of builtin PHP functions, and “function” is in the URL. It returns a bool, like a function would. The primary difference is that you get a parse error if you pass an expression rather than a comma-delimited list of one or more variables.
I think I have reconstructed the thought process behind this, and it’s a good point: “you know, PHP needs a way to inspect its environment at runtime to determine whether a particular variable has been instantiated. This is obviously perfectly suited for a built-in function. But wait! What if they call isset($a + "b"), which is not a bare variable?”
php > $a = 2; if(isset($a+"b")) { echo "true\n"; } else { echo "false\n"; }
Parse error: parse error, expecting’,” or ')'' in php shell code on line 1
My solution, assuming we can’t interpolate the result of the expression and arrive at “ab”, would be to return false. It’s not a variable. Therefore it is not set. Perhaps one would prefer it to return NULL, indicating the question has no answer. I’m big on generalizing and minimizing special snowflake cases. This is not, in my opinion, such a profound problem of engineering as to justify a massive exception to the concept of functions.
Of course, isset() is not the only pseudo-function implemented like this; empty(), unset(), and probably others exist. However:
php > const a = 2; if(defined('a')) { echo "true\n"; } else { echo "false\n"; }
true
php > const a = 2; if(defined('a'+'b')) { echo "true\n"; } else { echo "false\n"; }
false
Look at that! defined() uses the exact implementation I have suggested, but isset() does not. You can throw anything into the argument of defined() - some numbers, NULL, whatever - and it will return false without throwing a hissy fit. I note that defined() takes a string argument, which is, I assume, the key implementation difference (please don’t make me go look, I don’t want to go back to the dark place). (Also, allow me to complain how these functions are vaguely named, which requires that you look them up in documentation.) Seriously, what the hell is this, what are you doing with your life PHP, special casing all over the place and doing so inconsistently, didn’t your mother ever tell you - deep breath, sorry about that. I get really worked up about programs sometimes.
Anyway - remember what I was saying about special snowflake functions?
The filter class apparently has its own, slightly different implementation, which will only test the arrays used to store user inputs. Why did they need to clutter up the runtime with a nearly identical implementation instead of isset()? Perhaps they were annoyed by stupid, pointless parse errors and reimplementing under the standard library’s nose was easier than getting it changed. I don’t know. Perhaps there was a really good reason they needed a separate isset(), having to do with the undocumented fact that it tests the original input array sans any runtime changes. I don’t know, because PHP never, ever documents the reason for squat.
php > if(isset(NULL)) { echo "true\n"; } else { echo "false\n"; }
Parse error: parse error, expecting 'T_PAAMAYIM_NEKUDOTAYIM' in php shell code on line 1
wat