I inherited a codebase that is filled with conditionals using terms like (isset($a) && !empty($a)) but the $a are actually long variable names and it's an eye-sore. I wanted to replace the expressions with $a??false but I wasn't sure if there was some case that wouldn't be the same.
Are these statements identical or is there some value of $a that would be different?
CodePudding user response:
Firstly, let's understand what the different elements are doing:
issettakes a variable, array element, etc, and returns true if it exists, and has any value other than nullemptytakes a variable, array element, etc, and returns false if it exists, and has any value which would be considered equivalent totrue??examines a variable, array element, etc, and returns its value if it exists, and has any value other than null; otherwise, it returns its right-hand argument- any expression used in an
ifstatement is cast to boolean automatically
So, we can look at the equivalences:
emptyis a combination ofisset()and a cast to false; specifically,empty($a) === !isset($a) || !(bool)$a, so!empty($a) === isset($a) && (bool)$a??uses the same check asisset, not the same check asempty; so$a ?? falseon its own is equivalent toisset($a) ? $a : false- but, in an
ifstatement, the whole thing will be forced to boolean, soif ( $a ?? false ) ...is equivalent toif ( (bool)(isset($a) ? $a : false) ) ...or more readablyif ( isset($a) ? (bool)$a : false ) ...
Which brings us to the answer, which is that the following all do the same thing:
if ( isset($a) && !empty($a) ) ...
if ( isset($a) && !(bool)$a ) ... // empty() is just a bool cast isset
if ( !empty($a) ) ... // the isset is actually redundant
if ( isset($a) ? (bool)$a : false ) ... // same logic as the && version
if ( (bool)($a ?? false) ) ... // ?? does the isset for us
if ( $a ?? false ) ... // if does the (bool) for us
Probably the most readable is just to use !empty($a) on its own, and leave ?? for where you actually need the original value rather than a true.
