More concise ternary expression?

I often have to write code with the following logical pattern:

$foo = isset($bar) ? $bar : $baz; 

I know about the syntax ?: ::

 $foo = $bar ?: $baz; 

... which, at first glance, seems to be what I'm looking for; however, it highlights the notification index undefined if $bar not set. It also uses the same logic as empty() , which means that "empty" values, such as FALSE , 0 , "0" , etc., do not pass. Therefore, this is not entirely equivalent.

Is there a shorter way to write this code without throwing a notification when $bar not set?

Edit:

To make it clearer why I'm looking for shortcut syntax, here is a better example:

 $name = isset($employee->getName()) ? $employee->getName() : '<unknown>'; 

In this case, $employee may be an object from a third-party library, and there may be a valid scenario that its name may be NULL . I would like to set the $name variable to the return name (if any), but some reasonable defaults if they are not.

If the method call is more complicated than just getter, then the example becomes even more verbose, since we have to cache the result:

 $bar = $some->reallyExpensiveOperation(); $foo = isset($bar) ? $bar : $baz; 
+6
source share
3 answers

I would only use short-hand syntax when you explicitly predefine your variables or use an object with a magic getter. This is a very simple example of where I usually use short hand syntax.

 class Foo { public function __get($name) { return isset($this->{$name}) ? $this->{$name} : ''; } } $foo = new Foo(); $bar = $foo->baz ?: 'default'; 
+3
source

Using the error management operator , you can technically shorten it to:

 $foo = @$bar ?: $baz; 

If $bar not set, the value is null and you do not receive error notifications because you suppressed the error. Some, however, may not approve of this code, since it is not recommended to use @ , as it disguises errors and makes debugging difficult.

Without this, I don’t believe that there is a shorter notation using only isset .

Edit: as @drrcknlsn noted, this will not work if the variables are false or 0 , or even null , so it seems to me that isset should not be avoided.

0
source

If $bar not defined, there really is no β€œshorter” way to write the same code.

There are two that I consider "hacks" for this, however they can also influence other things:

  • Throttling error with @ , for example $foo = @$bar ?: $baz; , will do exactly what you want and activate undefined -error, which if $bar undefined. If defined, it will also work as desired. However, the downside is that @ can reduce the efficiency in your code if it is reused.
  • Disabling notifications using error_reporting(E_ALL & ~E_NOTICE); . This will still display all regular errors, but simply not notifications that will effectively hide the "undefined variable" error. The disadvantage of this is that you will not see any other notifications.

Now, my mandatory personal opinion, I would advise you to continue to write it in full. The ternary operator is already shortened, effectively reducing the following:

 if (isset($bar)) { $foo = $bar; } else { $foo = $baz; } 

in a much shorter

 $foo = isset($bar) ? $bar : $baz; 

and in fact, it doesn’t take much more effort to write a full triple and a shorter triple (unless, of course, the names of the variables are ridiculously long). In addition, there will be several examples when complex ternary operations (i.e. several triple in one), which will lead to the fact that unnecessary shorthand will become unsuitable; therefore, short-term savings are not programmatically / morally satisfactory (in my opinion).

UPDATE:. To support your editing, in which you assign $bar return value of the function, and then $foo based on it, you can combine the operators in a single -line like:

 $foo = (($bar = $some->reallyExpensiveOperation()) != null) ? $bar : $baz; 

This is almost the same code length as two lines, but here it can also be shortened a bit. For example, if null not the only value that you consider to be "invalid", but false also taken into account, you can completely remove the != null and allow the condition to be considered as a simple Boolean value:

 $foo = ($bar = $some->reallExpensiveOperation()) ? $bar : $baz; 

In this example, $bar is still available after the triple operation (i.e., it does not lose its scope), so if you do not need to preprocess the variable, there is no big drawback in this method, except for readability.

0
source

Source: https://habr.com/ru/post/921007/


All Articles