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'];
}
Related
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 have a operator in a string .
$c['operator'] = ">=";
if($sub_total.$c['operator'].$c['value'])
{
echo $sub_total.$c['operator'].$c['value'];
}
it obtain output is 20610>=30000
I'd put the possible operators in a switch:
$result = null;
switch($c['operator'])
{
case '>=':
$result = $sub_total >= $c['value'];
break;
case '<=':
$result = $sub_total <= $c['value'];
break;
// etc etc
}
This is far safer than using eval, and has the extra benefit that it sanitises the input.
$sub_total.$c['operator'].$c['value'] is not a comparison but a string concatenation. A filled string is always true in PHP, hence the if-statement is always true.
String can't be interpreted as php code unless you use eval (be careful with it).
What you are doing in your example in if statement is that you concatenate strings and because string after concatenation is not null it's evaluated to true, so if statement is executed.
In your case solution would be to see which operator is used like #adam has written in his solution.
BTW, having logic in strings (and possibly outside of script) is not a good idea.
Use PHP eval to evaluate the code you constructed.
$c['operator'] = ">=";
if(eval($sub_total.$c['operator'].$c['value']))
{
echo $sub_total.$c['operator'].$c['value'];
}
You can't do that in PHP, you should do something like below :
if ($c['operator'] == '>=' and $sub_total >= $c['value']) {
// Do something
} else if ($c['operator'] == '<=' and $sub_total <= $c['value']) {
// Do something else
} // etc...
Take a look at the eval method. It's very dangerous though
http://php.net/manual/en/function.eval.php
Given the following code:
if (is_valid($string) && up_to_length($string) && file_exists($file))
{
......
}
If is_valid($string) returns false, does the php interpreter still check later conditions, like up_to_length($string)?
If so, then why does it do extra work when it doesn't have to?
Yes, the PHP interpreter is "lazy", meaning it will do the minimum number of comparisons possible to evaluate conditions.
If you want to verify that, try this:
function saySomething()
{
echo 'hi!';
return true;
}
if (false && saySomething())
{
echo 'statement evaluated to true';
}
Yes, it does. Here's a little trick that relies on short-circuit evaluation. Sometimes you might have a small if statement that you'd prefer to write as a ternary, e.g.:
if ($confirmed) {
$answer = 'Yes';
} else {
$answer = 'No';
}
Can be re-written as:
$answer = $confirmed ? 'Yes' : 'No';
But then what if the yes block also required some function to be run?
if ($confirmed) {
do_something();
$answer = 'Yes';
} else {
$answer = 'No';
}
Well, rewriting as ternary is still possible, because of short-circuit evaluation:
$answer = $confirmed && (do_something() || true) ? 'Yes' : 'No';
In this case the expression (do_something() || true) does nothing to alter the overall outcome of the ternary, but ensures that the ternary condition stays true, ignoring the return value of do_something().
Bitwise operators are & and |.
They always evaluate both operands.
Logical operators are AND, OR, &&, and ||.
All four operators only evaluate the right side if they need to.
AND and OR have lower precedence than && and ||. See example below.
From the PHP manual:
// The result of the expression (false || true) is assigned to $e
// Acts like: ($e = (false || true))
$e = false || true;
// The constant false is assigned to $f before the "or" operation occurs
// Acts like: (($f = false) or true)
$f = false or true;
In this example, e will be true and f will be false.
Based on my research now, PHP doesn't seem to have the same && short circuit operator as JavaScript.
I ran this test:
$one = true;
$two = 'Cabbage';
$test = $one && $two;
echo $test;
and PHP 7.0.8 returned 1, not Cabbage.
No, it doesn't anymore check the other conditions if the first condition isn't satisfied.
I've create my own short-circuit evaluation logic, unfortunately it's nothing like javascripts quick syntax, but perhaps this is a solution you might find useful:
$short_circuit_isset = function($var, $default_value = NULL) {
return (isset($var)) ? : $default_value;
};
$return_title = $short_circuit_isset( $_GET['returntitle'], 'God');
// Should return type 'String' value 'God', if get param is not set
I can not recall where I got the following logic from, but if you do the following;
(isset($var)) ? : $default_value;
You can skip having to write the true condition variable again, after the question mark, e.g:
(isset($super_long_var_name)) ? $super_long_var_name : $default_value;
As very important observation, when using the Ternary Operator this way, you'll notice that if a comparison is made it will just pass the value of that comparison, since there isn't just a single variable. E.g:
$num = 1;
$num2 = 2;
var_dump( ($num < $num2) ? : 'oh snap' );
// outputs bool 'true'
My choice: do not trust Short Circuit evaluation in PHP...
function saySomething()
{
print ('hi!');
return true;
}
if (1 || saySomething())
{
print('statement evaluated to true');
}
The second part in the condition 1 || saySomething() is irrelevant, because this will always return true. Unfortunately saySomething() is evaluated & executed.
Maybe I'm misunderstood the exact logic of short-circuiting expressions, but this doesn't look like "it will do the minimum number of comparisons possible" to me.
Moreover, it's not only a performance concern, if you do assignments inside comparisons or if you do something that makes a difference, other than just comparing stuff, you could end with different results.
Anyway... be careful.
Side note: If you want to avoid the lazy check and run every part of the condition, in that case you need to use the logical AND like this:
if (condition1 & condition2) {
echo "both true";
}
else {
echo "one or both false";
}
This is useful when you need for example call two functions even if the first one returned false.
I’m trying to shorten my code using the ternary operator.
This is my original code:
if ($type = "recent") {
$OrderType = "sid DESC";
} elseif ($type = "pop") {
$OrderType = "counter DESC";
} else {
$OrderType = "RAND()";
}
How can I use the ternary operator in my code instead of ifs/elses?
$OrderType = ($type = "recent") ? "sid DESC" : "counter DESC" ;
This is the code I tried, but have no idea how to add an “elseif part” to it.
This is called the ternary operator ;-)
You could use two of those :
$OrderType = ($type == 'recent' ? 'sid DESC' : ($type == 'pop' ? 'counter DESC' : 'RAND()'))
This can be read as :
if $type is 'recent'
then use 'sid DESC'
else
if $type is 'pop'
then use 'counter DESC'
else use 'RAND()'
A couple of notes :
You must use == or === ; and not =
The first two ones are comparison operators
The last one is the assignment operator
It's best to use (), to make things easier to read
And you shouldn't use too many ternary operators like that : it makes code a bit hard to understand, i think
And, as a reference about the ternary operator, quoting the Operators section of the PHP manual :
The third group is the ternary
operator: ?:. It should be used
to select between two expressions
depending on a third one, rather than
to select two sentences or paths of
execution. Surrounding ternary
expressions with parentheses is a very
good idea.
I'd suggest using a case statement instead. it makes it a little more readable but more maintainable for when you want to add extra options
switch ($type)
{
case "recent":
$OrderType = "sid DESC";
break;
case "pop":
$OrderType = "counter DESC";
break;
default:
$OrderType = "RAND()";
}
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.