As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I keep it in single line, if it's short. Lately I've been using this style for longer or nested ternary operator expressions. A contrived example:
$value = ( $a == $b )
? 'true value # 1'
: ( $a == $c )
? 'true value # 2'
: 'false value';
Personally which style you use, or find most readable?
Edit: (on when to use ternary-operator)
I usually avoid using more than 2 levels deep ternary operator. I tend prefer 2 levels deep ternary operator over 2 level if-else, when I'm echoing variables in PHP template scripts.
The ternary operator is generally to be avoided, but this form can be quite readable:
result = (foo == bar) ? result1 :
(foo == baz) ? result2 :
(foo == qux) ? result3 :
(foo == quux) ? result4 :
fail_result;
This way, the condition and the result are kept together on the same line, and it's fairly easy to skim down and understand what's going on.
I try not to use a ternary operator to write nested conditions. It defies readability and provides no extra value over using a conditional.
Only if it can fit on a single line, and it's crystal-clear what it means, I use it:
$value = ($a < 0) ? 'minus' : 'plus';
a style I sometimes use, which I'm bringing up since it hasn't been mentioned, is like this:
$result = ($x == y)
? "foo"
: "bar";
..but usually only if putting it all on one line makes it too long. I find that having the = ? : all line up makes it look neater.
Personally, I only use the ternary operator if it fits on one line. If it need to span, then it's time for the good old
if else if else
PHP nested ternary operators behave differently.
This syntax passes all the following tests.
Based on http://deadlytechnology.com/web-development-tips/php-ternary-syntax/
$myvar = ($x == $y)
?(($x == $z)?'both':'foo')
:(($x == $z)?'bar':'none');
.
See: http://au.php.net/ternary
Example #3 "Non-obvious Ternary Behaviour" explains why the following does not work in PHP.
$x = 1;
$y = 2;
$z = 3;
$myvar = ($x == $y)
? "foo"
: ($x == $z)
? "bar"
: "none";
$myvar == 'none'; // Good
$x = 1;
$y = 2;
$z = 1;
$myvar = ($x == $y) ? "foo" : ($x == $z) ? "bar" : "none";
$myvar == 'bar'; // Good
$x = 1;
$y = 1;
$z = 3;
$myvar = ($x == $y) ? "foo" : ($x == $z) ? "bar" : "none";
$myvar == 'bar'; // Bad!
$x = 1;
$y = 1;
$z = 1;
$myvar = ($x == $y) ? "foo" : ($x == $z) ? "bar" : "none";
$myvar == 'bar'; // Bad!
ternary operators are short effective ways to write simple if statements. They shouldn't be nested or difficult to read. Remember: You write the software once but is is read 100 times. It should be easier to read than write.
I tend to enclose the condition in parentheses : (a == b) ? 1 : 0
I'll dissent with the common opinion. I'm sort of like Imran with my conditional operator style. If it fits cleanly on one line, I keep it on one line. If it doesn't fit cleanly on one line, I do break it, but I use only a single tab (4 spaces; I have VS set to insert spaces for tabs) for the indent. I don't immediately jump to if-else, because a lot of the time the conditional operator makes more sense contextually. (If it doesn't make sense contextually, however, I simply don't use it.)
Also, I don't nest conditional operators. At that point, I do find it too difficult to read, and it's time to go to the more verbose if-else style.
The ternary conditional can make code cleaner and more elegant, and most importantly, help you put emphasis on the right things and avoid repeating yourself. Consider using them, but do not make the code less readable by doing so. In VB.NET:
'before refactoring
If x = 0 Then ' If-Then-Else puts emphasis on flow control
label = "None"
Else
label = Foo.getLabel(x) ' If-Then-Else forces repeat of assignment line
End If
'after refactoring
label = If(x = 0, "None", Foo.getLabel(x)) ' ternary If puts emphasis on assignment
Note that "it is less readable" is not the same thing as "I'm not used to seeing that".
The "contrived example" is how I would indent it, except that I would indent from the left margin, not based on where the ( or whatever is on the line above.
To the ternary detractors - readability is the point. If you don't think it makes for more readable code, don't use it. But I find the contrary to be the case at least some of the time.
I don't use it. It always smelled to me like trying to save space and typing in source code with the expectation that small source == more efficient compiled code.
I don't find it readable at all, but much of that is because I just never use it.
Imran, you have formatted this beautifully. However, the ternary operator does tend to get unreadable as you nest more than two. an if-else block may give you an extra level of comprehensible nesting. Beyond that, use a function or table-driven programming.
$foo = (isset($bar)) ? $bar : 'default';
I personally only use it for an assignment of a variable (in java) for example :
String var = (obj == null) ? "not set" : obj.toString();
and (other example) when using function that doesn't allow null parameter such as :
String val; [...]
int var = (val == null) ? 0 : Integer.parseInt(val);
I tend not to use the ternary operator at all as I find if .. else much more readable.
Related
Recently i came upon such snippet:
$x = 2 && $y = 3; echo (int)$x.':'.(int)$y;
Which produces output 1:3.
By looking at operator precedence sheet i see that logical operators || and && has higher precedence than assignment operator =. So first expression should be evaluated as $x = (2 && $y) = 3; which becomes $x = (2 && null) = 3; and finally evaluates to $x = false = 3; Secondly - assignment operator has right associativity, so interpreter should try to execute false = 3 which is illegal of course. So in my opinion above mentioned code snippet should not compile at all and must throw parse or run-time error. But instead of that script produces 1:3. Which means that interpreter executed actions are:
a) $y=3
b) 2 && $y
c) $x = (2 && $y)
Why it is so and not according to operator precedence ?
The operator precedence sheet you link to states as a separate note:
Although = has a lower precedence than most other operators, PHP will
still allow expressions similar to the following: if (!$a = foo()), in
which case the return value of foo() is put into $a.
So, in effect, an assignment inside an expression will be treated somewhat like a sub-expression. Exactly how and when this will happen isn't clear from the documentation, which just states that "similar" expressions will work this way.
Apologies if this is basic, but I'm learning php.
What does this snippet of code actually do? I've seen it in the source code for a plugin but can't quite figure out what's going on
$_POST['newName'] = $_POST['newName'] == "" ? "Dude" : $_POST['newName'];
Thanks.
This is a short version of if...else. This is a Ternary Logic.
$_POST['newName'] = $_POST['newName'] == "" ? "Dude" : $_POST['newName'];
if $_POST['newName'] == "" is true then "Dude" and else $_POST['newName'].
and both the value will be set in $_POST['newName'].
You can write this like this: [Full form]
if($_POST['newName'] == "")
$_POST['newName'] = "Dude";
The ? is also known as the ternary operator. It is called the ternary operator because it takes three operands - a condition, a result for true, and a result for false. If that sounds like an if statement to you, you are right on the money - the ternary operator is a shorthand (albeit very hard to read) way of doing if statements. Here's an example:
<?php
$agestr = ($age < 16) ? 'child' : 'adult';
?>
First there is a condition ($age < 16), then there is a question mark, and then a true result, a colon, and a false result. If $age is less than 16, $agestr will be set to 'child', otherwise it will be set to 'adult'. That one-liner ternary statement can be expressed in a normal if statement like this:
<?php
if ($age < 16) {
$agestr = 'child';
} else {
$agestr = 'adult';
}
?>
So, in essence, using the ternary operator allows you to compact five lines of code into one, at the expense of some readability.
Sometimes while coding, you might feel that writing an if(...){...}else{...} might feel like overkill for small amounts of code:
$result;
if (20>3)
{
$result = "bigger!";
}
else
{
$result = "smaller!";
}
So for this reason, a short hand notation was created where you would be able to express the exact same statement but without the need for such a big structure:
$result = (20>3) ? "bigger!" : "smaller!" ;
Whatever is between = and ? would then be the condition that is normally between the ( and ) of if(...). If that expression then equates to true, the value obtained by $result would be: "bigger!", and if it equated to false, the result would be: "smaller!".
As Frayne said, it is the shortened version of conditional statement. When we write it in full form, it becomes this:
<?php
if($_POST['newName'] == "") {
$_POST['newName'] = "Dude";
} else {
$_POST['newName'] = $_POST['newName'];
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
Ok,
so consider the following:
$this->foo = isset($_GET['foo']) && !empty($_GET['foo']) ? $_GET['foo'] : NULL;
and this:
$this->foo = (isset($_GET['foo']) && !empty($_GET['foo'])) ? $_GET['foo'] : NULL;
When I write an if / else statement with multiple checks, I generally include the extra parenthesis as in the second example. In the ternary, both examples work.
Should I add the extra parenthesis as on the bottom? Or go with the first?
Thanks
Operator precedence is the issue as to when parenthesis are necessary (notwithstanding readability).
When dealing with the ternary operator look at the order PHP uses to group expressions, start with the ternary operator(s) and examine the operators that are grouped after the ternary operator. Those are the operators that have the potential to produce erroneous output.
PHP Operator Precedence, starting with ternary:
Assoc. Operators Additional Information
...
left ? : ternary
right = += -= *= **= /= .= %=
&= %= &= |= ^= <<= >>= => assignment
left and logical
left xor logical
left or logical
left , many uses
In this case there are the assignment operators, the lower precedence logical operators, and comma.
It appears the ternary and assignment are equal, therefore grouping is determined by their associativity when the two are in the same statement.
$a = true? 'yes': 'no';
// $a is assigned 'yes'
Assignment is right associative so, in relation to the =, expressions are grouped right to left. In this case the ternary comes first (rightmost) and the statement works as expected.
That leaves the lower precedence boolean and the comma.
echo true and true? 'yes': 'no';
// Echos: 1
// Grouped like: echo true and (true? 'yes': 'no');
Not as expected. Use parenthesis to force intended grouping:
echo (true and true)? 'yes': 'no';
// Echos: yes
When using higher precedence boolean operators, which are grouped before the ternary operator, parenthesis are not necessary.
echo true && true? 'yes': 'no';
// Echos: yes
Bottom line, when operator precedence is unclear, or readability is desired, use parenthesis.
The PSR-2 standard specifically omits any opinion on operators. But in this case, i'll go with the simple one:
$this->foo = isset($_GET['foo']) && !empty($_GET['foo']) ? $_GET['foo'] : NULL;
I am for the first approach:
$this->foo = isset($_GET['foo']) && !empty($_GET['foo']) ? $_GET['foo'] : NULL;
simplified to
$this->foo = !empty($_GET['foo']) ? $_GET['foo'] : NULL;
empty already check the isset. I would include parathenis in this case only when condition has more then 3 statements. Consider that the 1 line if/else normally is used when the condition is simple, other wise to have a more readable if else you should go with classic if {} else {}
I understand whiles, ifs, fors, cases, arrays, functions, and other syntactic constructs and my coding experience is 70’s style Fortran and T-SQL.
Now I’m trying to understand PHP, but it occasionally seems to compress several statements into one obfuscating line of code. What’s the expanded equivalent of the following single line of PHP below?
$start = gt("start") === false ? 0 : intval(gt("start"));
It is a ternary operator. They're usually of the following format:
expr1 ? expr2 : expr3;
Which means:
if expr1 then return expr2 otherwise return expr3
It can be visualized as follows:
Your code can be rewritten as:
if (gt("start") === false) {
$start = 0;
} else {
$start = intval(gt("start"));
}
It can improved as follows, to avoid an extra function call:
if (($result = gt("start")) === false) {
$start = 0;
} else {
$start = intval($result);
}
This ? is known as the ternary operator. It is a shorthand, e.g.
$x = a ? $b : $c; // where 'a' is some expression, variable or value
could also be written:
if (a) {
$x = $b;
}
else {
$x = $c;
}
Essentially, if expression a evaluates equal to TRUE, then the ternary operator returns b, otherwise it returns c.
Others have posted answers that do a good job of explaining the basics of how a ternary operator works, but to visualize what a ternary is versus an if/else you can do the following. Look at your example:
$start = gt("start") === false ? 0 : intval(gt("start"));
Now let’s make it one line using if/else:
if (gt("start") === false) { $start = 0; } else { $start = intval(gt("start")); }
When you see it lined up like that the immediate take-away—beyond the basic structure—is you must set $start = within each conditional.
So knowing that, them main benefit of a ternary operator is quick if/else logic to assign a value to a single variable.
The convenience of this from a coding standpoint is one can quickly disable that logic by just commenting out one line while debugging instead of having to comment out multiple lines of an if/else.
I am trying to write would be a simple if condition.
function genderMatch($consumerid1, $consumerid2)
{
$gender1=getGender($consumerid1);
$gender2=getGender($consumerid2);
echo $gender1;
echo $gender2;
if($gender1=$gender2)
echo 1;
return 1;
else
echo 0;
return 0;
}
The output of the getGender function is either a M or F. However, no matter what I do gender1 and gender2 are returned as the same. For example I get this output: MF1
I am currently at a loss, any suggestions?
if ($gender1 = $gender2)
assigns the value of $gender2 to $gender1 and proceeds if the result (i.e. the value of $gender2) evaluates to true (every non-empty string does). You want
if ($gender1 == $gender2)
By the way, the whole function could be written shorter, like this:
function genderMatch($cid1, $cid2) {
return getGender($cid1) == getGender($cid2);
}
You have to put two == for comparison. With only one, as you have right now, you are assigning the value to the first variable.
if($gender1=$gender2)
would become
if($gender1==$gender2)
this:
if($gender1=$gender2)
should be
if($gender1==$gender2)
notice the extra ='s sign. I think you might also need curly brackets for multiple lines of an if/else statement.
Your using the assignment operator = instead of comparsion operators == (equal) or === (identical).
Have a look at PHP operators.
You have some structural problems with your code as well as an assignment instead of a comparison.
Your code should look like this:
function genderMatch($consumerid1, $consumerid2){
$gender1=getGender($consumerid1);
$gender2=getGender($consumerid2);
echo $gender1;
echo $gender2;
if($gender1==$gender2){
echo 1;
return 1;
}else{
echo 0;
return 0;
}
}
Notice the double '=' signs in the if statement. This is a comparison. A single '=' is an assignment. Also, if you want to execute more than 1 line of code with an if/else, you need brackets.
You are using a single = which sets the variable, ie. the value of $gender1 is set to be the value of $gender2.
Use the === operator instead: if($gender1 === $gender2). It is usually a good idea to do strict comparisons rather than loose comparisons.
Read more about operators here: php.net
Another alternative is to use strcmp($gender1, $gender2) == 0. Using a comparer method/function is more common in languages where the string-datatype isn´t treated as a primary data-type, eg. C, Java, C#.