Newer style PHP ternary operator has undesired result with isset function - php

I am having issue with PHP's ternary operator, since PHP version 5.3 you are able to replace the shorthand ternary operator with an even shorter version
// Older version
$route = isset($test) ? $test : 'test is NOT set';
// Newer version as of 5.3
$route = isset($test) ?: 'test is NOT set';
Now on the newer version, if $test is not set. it works fine. However when it is set because of the isset() method, it is returning true or 1 instead of the value.
Do I have to use the older longer method to get $route to equal the value of $test instead of a boolean value of 1 ?

You have to use the longer version.
Quoting the docs:
Expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE, and expr3 otherwise.
So the correct behaviour for your shorthand version is to return the result of evaluating isset($test). Not of $test as you want.

Starting from PHP 7, you can use the null coalescing operator:
$route = $test ?? 'test is NOT set';
which is equivalent to
$route = isset($test) ? $test : 'test is NOT set';
Here you can find some details:
The null coalescing operator (??) has been added as syntactic sugar for the common case of needing to use a ternary in conjunction with isset(). It returns its first operand if it exists and is not NULL; otherwise it returns its second operand.

Related

Operator Precedence && and?

Am I reading https://www.php.net/manual/en/language.operators.precedence.php that && binds tighter than ?? ?
Why the heck would a construct that's designed to provide a "default value" of an optional array element not bind very tightly to that element?
$ok = $ok && $someArray['optionalElement'] ?? true; // Wrong
$ok = $ok && ( $someArray['optionalElement'] ?? true ); // Right
From the PHP Docs
https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.null-coalesce-op
The null coalescing operator (??) has been added as syntactic sugar for the common case of needing to use a ternary in conjunction with isset(). It returns its first operand if it exists and is not NULL; otherwise it returns its second operand.
From this, the null coalescor treats everything to it's left as an expression argument to isset()
So $ok && $someArray['optionalElement'] is taken as a full expression.
Wrapping ( $someArray['optionalElement'] ?? true ) in parentheses causes only $someArray['optionalElement'] to be the expression and so it works as you would expect.

Is there a shorter syntax for the ternary operator in php?

How can I create a shorter expression of:
$variable = #$array["property"] ? $array["property"] : DEFAULT_VALUE_CONSTANT;
To something like this:
$variable = #$array["property"] || DEFAULT_VALUE_CONSTANT;
Now I get true / false
Yes it's possible in PHP7 with Null coalescing operator (??)
$variable = $array["property"] ?? DEFAULT_VALUE_CONSTANT;
If you are using PHP version < 7 one solution is use the elvis operator
$variable = $array["property"] ?: DEFAULT_VALUE_CONSTANT;
Please avoid using # instead of isset().
References:
?: operator (the 'Elvis operator') in PHP

What does `?:` mean?

In an online tutorial I have seen the following snippet of code:
$this->data = $data ?: \Input::all();
Is this a standard ternary operator? What would happen when $data evaluates to true?
Does the following code do the same thing as the original I posted?
$this->data = $data ? null : \Input::all();
It's a ternary operator, shortcut of
$this->data = $data? $data : \Input::all();
From http://php.net/manual/en/language.operators.comparison.php
Since PHP 5.3, it is possible to leave out the middle part of the ternary operator.
Expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE, and expr3 otherwise.

PHP IF[FALSE/NULL/EMPTY] function

Since a year or so I had a function in all my projects called: ifNot().
This function is somehow a derivated from the ternary operator:
public function ifNot( $item, $ifNot )
{
if ( !$item ) {
return $ifNot
} else {
return $item;
}
}
// The var $foo twice
$var = ( $foo ) ? $foo : 'is empty or false =(';
// The var $foo once
$var = ifNot($foo, 'is empty or false =(');
In fact, Twig Template Engine use something like it:
{{ foo ? 'yes' : 'no' }}
{# as of Twig 1.12.0 #}
{{ foo ?: 'no' }} == {{ foo ? foo : 'no' }}
{{ foo ? 'yes' }} == {{ foo ? 'yes' : '' }}
The question is: There is a better/known approach for this function?
PS: SQL also has an IFNULL() =)
Your function is essentially equivalent to a variant of the conditional operator that was added in PHP 5.3:
Since PHP 5.3, it is possible to leave out the middle part of the ternary operator. Expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE, and expr3 otherwise.
It may be a tiny bit faster to use the built-in approach if all your target environments are PHP 5.3 or greater, but I wouldn't really worry about it.
Yes, if your PHP is new enough (5.3.0 or newer). See the PHP documentation on the ternary operator
Since PHP 5.3, it is possible to leave out the middle part of the ternary operator. Expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE, and expr3 otherwise.
So while your code above is pretty awkward, there might be instances where you want a function version of this ternary operator (for example, to use as a callable - in those cases, you could just roll with a closure:
function($foo, $default) { return $foo ?: $default; }
$var = ifNot($foo, 'is empty or false =(');
is the same as:
$var = $foo?:'is empty or false =(';
In normal PHP (>= version 5.3) too. Your ifNot function is completely superfluous.

php var structure not clear

what does this structure mean:
$var = isset($var_1) ? $var_1 : $var_2;
I came across it and of course with other values, not $va, $var_1 and $var_2.
thanks.
This is the ternary operator, and means the same as:
if (isset($var_1)) {
$var = $var_1;
}
else {
$var = $var_2;
}
The ternary operator provides a short-hand method of creating simple if/else statements.
It has some syntax errors, correctly:
$var = isset($var_1) ? $var_1 : $var_2;
This means:
if (isset($var_1))
{
$var = $var_1;
}
else
{
$var = $var_2;
}
That means:
if(isset($var_1))
$var = $var_1;
else
$var = $var_2;
It is short syntax for that.
just for your information from the php manual i copy pasted good things to know about ternary comparision operators
The expression (expr1) ? (expr2) : (expr3) evaluates to expr2 if expr1 evaluates to TRUE, and expr3 if expr1 evaluates to FALSE.
Since PHP 5.3, it is possible to leave out the middle part of the ternary operator. Expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE, and expr3 otherwise.
Note: Please note that the ternary operator is a statement, and that it doesn't evaluate to a variable, but to the result of a statement. This is important to know if you want to return a variable by reference. The statement return $var == 42 ? $a : $b; in a return-by-reference function will therefore not work and a warning is issued in later PHP versions.
Note:
It is recommended that you avoid "stacking" ternary expressions. PHP's behaviour when using more than one ternary operator within a single statement is non-obvious:
Example #3 Non-obvious Ternary Behaviour
<?php
// on first glance, the following appears to output 'true'
echo (true?'true':false?'t':'f');
// however, the actual output of the above is 't'
// this is because ternary expressions are evaluated from left to right
// the following is a more obvious version of the same code as above
echo ((true ? 'true' : false) ? 't' : 'f');
// here, you can see that the first expression is evaluated to 'true', which
// in turn evaluates to (bool)true, thus returning the true branch of the
// second ternary expression.
?>

Categories