I often find myself needing to write code with the following logical pattern:
$foo = isset($bar) ? $bar : $baz;
I know about the ?:
syntax:
$foo = $bar ?: $baz;
...which, on the surface, appears to be what I'm looking for; however, it throws an undefined notice index when $bar
is not set. It also uses the same logic as empty()
, meaning that "empty" values like FALSE
, 0
, "0"
, etc. don't pass. Hence, it's not really equivalent.
Is there a shorter way of writing that code without throwing a notice when $bar
is not set?
Edit:
To make it a bit more clear why I'm looking for a shortcut syntax, here's a better example:
$name = isset($employee->getName())
? $employee->getName()
: '<unknown>';
In this case, $employee
might be an object from a 3rd-party library, and it might be a valid scenario that its name
might be NULL
. I'd like to set variable $name
to the returned name (if there is one), but some sensible default if there isn't.
If the method call is more complex than just a getter, then the example becomes even more verbose, since we have to cache the result:
$bar = $some->reallyExpensiveOperation();
$foo = isset($bar) ? $bar : $baz;
Using the error control operator you could technically shorten it to:
If
$bar
isn't set, the value evaluates to null, and you get no error notice since you suppressed the error. Some, however, might not approve of this code since its not nice to use@
since it masks errors and makes debugging more difficult.Without that, no I don't believe there is a shorter notation that just using
isset
.Edit: As noted by @drrcknlsn, this won't work if the variables are
false
, or0
, or evennull
, so it would seem to me that there is no avoiding the calling ofisset
.When
$bar
is not defined, there isn't really a "shorter" way to write the same code.There are two, what I would consider "hacks" to do it, however, they also may impact other things:
@
, such as$foo = @$bar ?: $baz;
will do exactly what you want and throttle the undefined-error that is thrown when$bar
is undefined. If it is defined, it will also work as desired. The downside is, however, that@
can reduce efficiency in your code if it's used repeatedly.error_reporting(E_ALL & ~E_NOTICE);
. This will still display all regular errors but just not the notices, which will effectively hide the "variable is undefined" error. The downside to this is that you will not see any other notices.Now, my obligatory personal opinion, I would suggest to continue writing it out full-hand. The ternary operator is already shorthand, effectively reducing the following:
into a much shorter
and it really doesn't take much more effort to write the full ternary versus the shorter-ternary (unless your variable names are ridiculously long, of course). Also, there are going to be more than a few instances where compound ternary operations (i.e. - several ternaries in one) that will cause the extra-shorthand to be unusable; so the short-savings is not programmatically/morally satisfying (in my own opinion).
UPDATE: To support your edit where you're assigning
$bar
to the return-value of a function and then$foo
based off of it - you can combine the statements into a single-line like:This is almost the same code-length as the two lines, but it can be shortened slightly from here as well. For instance, if
null
isn't the only value that you consider "not valid", butfalse
also counts, you can drop the!= null
portion entirely and allow the condition to be treated as a simple boolean value:In this example,
$bar
is still accessible after the ternary operation (i.e. - it doesn't lose scope), so unless you need to do pre-processing on the variable there isn't a big downside to this method, other than readability.I would only use the short hand ternary syntax when you explicitly predefine your variables or use an object with a magic getter. This is a very basic example of where I would normally use short hand ternary syntax