PHP Ternary Operators don't work as expected? [duplicate] - php

This question already has answers here:
Stacking Multiple Ternary Operators in PHP
(11 answers)
Closed 4 years ago.
I have a method that I'm checking if param is null, but if I use a ternary operator to make sure the false result isn't a string, I don't get the same expected result... I am a full stack .NET dev by day, but do some PHP free lance and this just stumped me...
$param = null;
// $active evaluates to true
$active = is_null($param) ? true : false;
// $active evaluates to false
$active = is_null($param) ? true : is_string($param)
? (strtolower($param) === 'true')
: true;
I have used nested ternary operators in C# and JavaScript what feels like countless times, but I don't know if I have ever tried in PHP... does PHP attempt to evaluate all nested ternary operations prior to expressing a result or is there something I'm missing here since from my understanding in this case, the ternary operator should be short circuited and evaluated to true in both circumstances.

The ternary operator is left associative unlike most other languages such as C#. The code:
$active = is_null($param)
? true
: is_string($param)
? (strtolower($param) === 'true')
: true;
is evaluated as follows:
$active = ((is_null($param) ? true : is_string($param))
? (strtolower($param) === 'true') : true);
You must explicitly add parenthesis to make sure ?: works the way it does in familiar languages:
$active = is_null($param)
? true
: (is_string($param)
? (strtolower($param) === 'true')
: true);

You need to wrap your second ternary condition with parenthesis (),
<?php
$param = null;
// $active evaluates to true
$active = is_null($param) ? true : false;
echo "Simple ternary result = $active".PHP_EOL;
// $active evaluates to true
$active = is_null($param) ? true : (is_string($param)? (strtolower($param) === 'true'): true);
echo "Nested ternary result = $active";
?>
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:
See Example #4 here at http://php.net/manual/en/language.operators.comparison.php
Example #4 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.
?>
DEMO: https://3v4l.org/gW8pk

This is a well-known problem with PHP. I doubt it will ever be fixed. Use parentheses, or if..else or switch statements, to get the behaviour you want.
(In technical terms, the ternary operator in PHP is "left associative", while that in every other language with this operator is "right associative". The latter is the more logical behaviour for this operator.)

Related

Can't replicate condition with ternary operator

I'm trying to replicate this condition:
$sth = $this->getResult();
if($sth !== true){
return $sth;
}
with ternary operator I tried with;
($sth !== true) ? return $sth : ($sth == true) ? null;
But I got:
Expected colon
What you're ultimately trying to achieve is not possible with a ternary operator.
What you try to do is ONLY return in 1 situation, and continue the code in the other. The only way you could do this using a ternary operator is like this:
$result = ($sth !== true) ? true : false;
if ($result) return;
But that kinda defeats the purpose of the ternary operator.
In fact, your code has a couple of problems:
Ternary operator always needs 3 parts (*)
There is no need to check a condition twice, as that's the entire point of the operator
The operator returns a value, so you can't put a return inside the truthy or falsy part.
A ternary operator needs 3 parts
(condition) ? truthy result : falsy result
Note: 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. - source: php.net
No need to check things twice:
Again, let's take our operator:
($sth !== true)
? "I return if '$sth' is not true"
: "I return if '$sth' is true";
There is no need to have a 2nd check. You have both situations covered already. :)
No return values inside the truthy or falsy part
Finally: it is an operator that returns a value. You can't put a return in the truthy or falsy part, you need to put it in front of it:
return ($sth !== true)
? "I return if '$sth' is not true"
: "I return if '$sth' is true";
You have two '?'s in your code, and only one ':'. I believe that's the matter. You must have the same amount of question marks as you have colons.
The ternary operator is nice and useful, but it's not a block of commands. It is a decision on a value. Rule of thumb, if you can assign something as value to a variable you can use it within the ternary operator :
$var = 3; // valid
($condition?3:0); // valid
$var = return 3; //Invalid
($condition?return 3:null) //Invalid
You need to:
return ($sth !== true?$sth:null);
If you are using it to return from a function I would do it like so:
function testFunc()
{
//arbitrary setting of $sth only to explain the point
$sth = false;
//condition ? true : false
$outcome = ($sth === true) ? true : false;
return $outcome;
}
// false
var_dump(testFunc());
Remember, (condition) ? value if true : value if false;
You can also miss out the [value if true] parameter, like so:
$outcome = ($sth === true) ?: false;
That expression would assign the value of $sth to $outcome if $sth was true.
Your replacement code indeed misses a colon at the very end. It is syntactically incorrect.
If $sth !== true you return $sth. If not, you start a new ternary statement (that is not complete) which I cannot properly fathom. It now does not look at all like the original statement.

Php a line need to underseand [duplicate]

This question already has answers here:
What are the PHP operators "?" and ":" called and what do they do?
(10 answers)
Closed 9 years ago.
what is the meaning of this line? Can any body help me? I have confusion on last 2 sign :''
why without this two sign browser make error? Thanks all.
isset($_POST['but'])? $_POST['but']:'';
U use the tenary comparison operator
A ternary operator have value for true and false
($contidition) ? true : false;
Please refer php documentation about ternary operator comparison operator
In case of:
isset( $_POST['but'] ) ? $_POST['but'] : ''
What it mean is, when $_POST['but'] exist, use it, otherwise use empty string
If u use php version > 5.3 u can use something like
isset($_POST['but']) ? : ''
It's just another way to write if/else statement.
For example:
$but = isset($_POST['but'])? $_POST['but']:'';
Would be the same as:
if(isset($_POST['but'])){
$but= $_POST['but'];
}else{
$but = '';
}
If $_POST request body contains but parameter - use it, overwise use empty string.
If you are misunderstood statement ? something : anything code - it's the Ternary Operator
It's nothing but the Ternary Operator
Explanation:
If your $_POST['but'] is set , then it will assign the same value to it , else it will set a ''
A clear example here
Well it's called an ternary operator.
Example:
$value = 5;
($value > 2) ? true : false; // returns true
The expression (expr1) ? (expr2) : (expr3) evaluates to expr2 if expr1 evaluates to TRUE, and expr3 if expr1 evaluates to FALSE.
(isset($_POST['but'])) ? $_POST['but']:'';
Here if your value $_POST['but'] is set then it will return $_POST['but'] else it will return ''.

php "?" operator - ($some_var) ? func() : func(); [duplicate]

This question already has answers here:
Closed 10 years ago.
($some_var) ? true_func() : false_func();
What is this in php, and what does this do? existence, boolean, or what?
It's the same thing as this:
if ($some_var) {
true_func();
}
else {
false_func();
}
If $some_val is true, it executes the function before the :.
If $some_val is false, it executes the function after the :.
It's called the ternary operator.
Typically it's used as an expression when assigning a value to a variable:
$some_var = ($some_bool) ? $true_value : $false_value;
It's one of the most abused programming constructs (in my opnion).
Taken from the PHP Manual: Comparison Operators
<?php
// Example usage for: Ternary Operator
$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];
// The above is identical to this if/else statement
if (empty($_POST['action'])) {
$action = 'default';
} else {
$action = $_POST['action'];
}
?>
It's the ternary operator.
Instead of writing
if ($a < $b) {
$minVal = $a;
} else {
$minVal = $b;
}
You can write is as
$minVal = ($a < $b) ? $a : $b;
It's actually a ternary operator. (I mean the operator ?: is a ternary operator).
($some_var) ? func1() : func2();
'$some_var' is a boolean expression.
If it evaluates to true 'func1()' is executed
else 'func2()' is executed.
Well, the way it's written, it does the same as just
func();
(If $somevar is true, invoke func; otherwise, invoke func too!)
it checks for boolean:
When converting to boolean, the following values are considered FALSE:
the boolean FALSE itself
the integer 0 (zero)
the float 0.0 (zero)
the empty string, and the string "0"
an array with zero elements
an object with zero member variables (PHP 4 only)
the special type NULL (including unset variables)
SimpleXML objects created from empty tags
Every other value is considered TRUE (including any resource).
Also have a look at: PHP type comparison tables

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.
?>

What does this PHP (function/construct?) do, and where can I find more documentation on it?

Simple question. Here is this code.
$r = rand(0,1);
$c = ($r==0)? rand(65,90) : rand(97,122);
$inputpass .= chr($c);
I understand what it does in the end result, but I'd like a better explanation on how it works, so I can use it myself. Sorry if this is a bad question.
If you're unsure of what I'm asking about, its the (function?) used here:
$c = ($r==0)? rand(65,90) : rand(97,122);
That's called a ternary operator. It's effectively the equivalent of
if ($r == 0) {
$c = rand(65, 90);
} else {
$c = rand(97, 122);
}
But it's obviously a bit more compact. Check out the docs for more info.
That simply means:
if($r==0){
$c = rand(65,90);
else{
$c = rand(97,122);
}
If the statement is true the first operation after that ? is executed, else the operation after : is executed.
Its called a ternary operator.
Its the Ternary Operator
<?php
// Example usage for: Ternary Operator
$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];
// The above is identical to this if/else statement
if (empty($_POST['action'])) {
$action = 'default';
} else {
$action = $_POST['action'];
}
?>
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.
It's called the ternary operator. It's similar to an if/else construct, but the difference is that an expression using the ternary operator yields a value.
That is, you can't set a variable to the result of an if/else construct:
// this doesn't work:
$c = if ($r == 0) {
rand(65, 90);
} else {
rand(97, 122);
}
You can read more about it here: http://php.net/ternary#language.operators.comparison.ternary
The ternary operator is frequently misused. There's little benefit to using it in the example you showed. Some programmers love to use compact syntactic sugar even when it's not needed. Or even when it's more clear to write out the full if/else construct.
The ternary operator can also obscure test coverage if you use a tool that measures lines of code covered by tests.

Categories