This question already has answers here:
Stacking Multiple Ternary Operators in PHP
(11 answers)
Closed 2 years ago.
How do I write a PHP ternary operator with the elseif portion?
I see basic examples with the if and else portions of the PHP ternary operator like this:
echo (true) ? "yes" : "no"; //prints yes
echo (false) ? "yes" : "no"; //prints no
How do I get the "elseif" portion like this into the ternary operator?
<?php
if($result->vocation == 1){
echo "Sorcerer";
}else if($result->vocation == 2){
echo 'Druid';
}else if($result->vocation == 3){
echo 'Paladin';
}else if($result->vocation == 4){
echo 'Knight';
}else if($result->vocation == 5){
echo 'Master Sorcerer';
}else if($result->vocation == 6){
echo 'Elder Druid';
}else if($result->vocation == 7){
echo 'Royal Paladin';
}else{
echo 'Elite Knight';
}
?>
A Ternary is not a good solution for what you want. It will not be readable in your code, and there are much better solutions available.
Why not use an array lookup "map" or "dictionary", like so:
$vocations = array(
1 => "Sorcerer",
2 => "Druid",
3 => "Paladin",
...
);
echo $vocations[$result->vocation];
A ternary for this application would end up looking like this:
echo($result->group_id == 1 ? "Player" : ($result->group_id == 2 ? "Gamemaster" : ($result->group_id == 3 ? "God" : "unknown")));
Why is this bad? Because - as a single long line, you would get no valid debugging information if something were to go wrong here, the length makes it difficult to read, plus the nesting of the multiple ternaries just feels odd.
A Standard Ternary is simple, easy to read, and would look like this:
$value = ($condition) ? 'Truthy Value' : 'Falsey Value';
or
echo ($some_condition) ? 'The condition is true!' : 'The condition is false.';
A ternary is really just a convenient / shorter way to write a simple if else statement. The above sample ternary is the same as:
if ($some_condition) {
echo 'The condition is true!';
} else {
echo 'The condition is false!';
}
However, a ternary for a complex logic quickly becomes unreadable, and is no longer worth the brevity.
echo($result->group_id == 1 ? "Player" : ($result->group_id == 2 ? "Gamemaster" : ($result->group_id == 3 ? "God" : "unknown")));
Even with some attentive formatting to spread it over multiple lines, it's not very clear:
echo($result->group_id == 1
? "Player"
: ($result->group_id == 2
? "Gamemaster"
: ($result->group_id == 3
? "God"
: "unknown")));
Since this would be a common task I would suggest wrapping a switch/case inside of a function call.
function getVocationName($vocation){
switch($vocation){
case 1: return "Sorcerer";
case 2: return 'Druid';
case 3: return 'Paladin';
case 4: return 'Knight';
case 5: return 'Master Sorcerer';
case 6: return 'Elder Druid';
case 7: return 'Royal Paladin';
default: return 'Elite Knight';
}
}
echo getVocationName($result->vocation);
echo ($result ->vocation == 1) ? 'Sorcerer'
: ($result->vocation == 2) ? 'Druid'
: ($result->vocation == 3) ? 'Paladin'
....
;
It’s kind of ugly. You should stick with normal if statements.
How to write a basic PHP Ternary Operator:
($your_boolean) ? 'This is returned if true' : 'This is returned if false';
Example:
$myboolean = true;
echo ($myboolean) ? 'foobar' : "penguin";
foobar
echo (!$myboolean) ? 'foobar' : "penguin";
penguin
A PHP ternary operator with an 'elseif' crammed in there:
$chow = 3;
echo ($chow == 1) ? "one" : ($chow == 2) ? "two" : "three";
three
But please don't nest ternary operators except for parlor tricks. It's a bad code smell.
I'd rather than ternary if-statements go with a switch-case. For example:
switch($result->vocation){
case 1:
echo "Sorcerer";
break;
case 2:
echo "Druid";
break;
case 3:
echo "Paladin";
break;
case 4:
echo "Knight";
break;
case 5:
echo "Master Sorcerer";
break;
case 6:
echo "Elder Druid";
break;
case 7:
echo "Royal Paladin";
break;
default:
echo "Elite Knight";
break;
}
You wouldn’t: it’s messy and hard to read.
You’re looking for the switch statement in the first case. The second is fine as it is but still could be converted for consistency
Ternary statements are much more suited to boolean values and alternating logic.
To be honest, a ternary operator would only make this worse, what i would suggest if making it simpler is what you are aiming at is:
$groups = array(1=>"Player", 2=>"Gamemaster", 3=>"God");
echo($groups[$result->group_id]);
and then a similar one for your vocations
$vocations = array(
1=>"Sorcerer",
2=>"Druid",
3=>"Paladin",
4=>"Knight",
....
);
echo($vocations[$result->vocation]);
With a ternary operator, you would end up with
echo($result->group_id == 1 ? "Player" : ($result->group_id == 2 ? "Gamemaster" : ($result->group_id == 3 ? "God" : "unknown")));
Which as you can tell, only gets more complicated the more you add to it
In addition to all the other answers, you could use switch. But it does seem a bit long.
switch ($result->vocation) {
case 1:
echo 'Sorcerer';
break;
case 2:
echo 'Druid';
break;
case 3:
echo 'Paladin';
break;
case 4:
echo 'Knight';
break;
case 5:
echo 'Master Sorcerer';
break;
case 6:
echo 'Elder Druid';
break;
case 7:
echo 'Royal Paladin';
break;
default:
echo 'Elite Knight';
break;
}
You could also do:
echo "yes" ?: "no" // Assuming that yes is a variable that can be false.
Instead of:
echo (true) ? "yes" : "no";
PHP 8 (Left-associative ternary operator change)
Left-associative ternary operator deprecation https://wiki.php.net/rfc/ternary_associativity.
The ternary operator has some weird quirks in PHP. This RFC adds a deprecation warning for nested ternary statements. In PHP 8, this deprecation will be converted to a compile time error.
1 ? 2 : 3 ? 4 : 5; // deprecated
(1 ? 2 : 3) ? 4 : 5; // ok
source: https://stitcher.io/blog/new-in-php-74#numeric-literal-separator-rfc
Related
I not understand little bit. Simple switch statement not working correctly with zero value (=0):
//$result = $sql->fetchColumn();
$result = 1;
switch ($result) {
case $result <= 2 :
throw new Exception('Error!');
break;
}
Problem is when $result = 0 then output should be 'error' but in this case script passing this validation. Weird question but i can't find a problem.
You can write it like that:
<?php
switch ($i) {
case 0:
case 1:
case 2:
throw new Exception('Error!');
break;
case 3:
echo "i is 3 or higher.";
}
?>
As I said in my comment above, you can't use "grater than" "less than" etc. in a switch-statement. As other said, if you want to make use of them, use a simple IF statement.
this code
switch ($result) {
case $result <= 2 :
is equivalent
if($result == ($result <= 2))
and when
$result=0
we have
( 0 == true )
after type conversion
false === true
and this is false as expected
whats wrong with my switch ?
Now result:
< more
> less
= equality
!= no't equality
As it should be:
< more
= equality
<?php
$page = 99;
switch ($page)
{
case $page < 121:
echo '< more <br/>';
case $page > 123:
echo '> less <br/>';
case $page == 99:
echo '= equality <br/>';
case $page != 99:
echo '!= no\'t equality <br/>';
}
?>
In your switch statement you're comparing a number with boolean values.
Let's take the first case $page < 121 is true, so the comparison taking place is 99==true which is true according to http://docs.php.net/language.types.type-juggling (switch performs a loose comparison, not a strict like ===). Thus the first case block is executed.
And since you don't have a break statement it falls through to the next case block and the next and so on...
Meaning: This won't work as intended regardless of whether you use break or not.
You don't seem to understand how switch works. What you want is a series of if statements, i.e.
if ($page < 121)
echo '< more <br/>';
if ($page > 123)
echo '> less <br/>';
if ($page == 99)
echo '= equality <br/>';
if ($page != 99)
echo '!= no\'t equality <br/>';
Switch is to be used only when you want to compare a variable against a set of values.
switch ($variable)
{
case "me":
echo "variable is me";
break;
case "you":
echo "variable is you";
break;
default:
echo "Variable is neither of us";
}
The above switch case block can be written as shown below:
if ($variable=="me")
{
echo "variable is me";
}
elseif ($variable=="you")
{
echo "variable is you";
}
else
{
echo "variable is neither of us";
}
DO NOT put an expression near the case statement.
switch ($somethng)
{
case $something < 10:
break;
case $something > 20:
break;
}
Switch is meant to be used only for comparing a variable against a set of values. ONLY! For everything else use a if...elseif..else statement.
The block above is wrong usage. Sometimes more than one of those expressions could be true.
$var = "cat";
switch($var)
{
case "cat":
echo 'My '.$var.' is called Bob.';
break;
case "dog":
echo 'My '.$var.' is called James.';
break;
default:
echo "I don't have an animal";
break;
}
In a switch statemant you compare $var against value in a case. If there is a match, the actual case will be executed, otherwise the default will be executed. You can't use <>!=... in a case, only values like: 1, '1', 'dog', $var2, and so on.
If you want to run the same command for two case you can do:
$var = "cat";
switch($var)
{
case "cat":
case "dog":
echo 'My '.$var.' is called James.';
break;
default:
echo "I don't have an animal";
break;
}
In your code, your forgot to put break; at the end of each case, that's why you see 'everything' in your output. And you miss default: too.
For the task you're doing, i suggest you to use if statements.
if iam not wrong you can't use this characters < > raw in html. use instead the entities > and <.
if you run the script in the command line i got following output.
<?php
ob_start();
$page = 99;
switch ($page)
{
case $page < 121:
echo '< more <br/>';
case $page > 123:
echo '> less <br/>';
case $page == 99:
echo '= equality <br/>';
case $page != 99:
echo '!= no\'t equality <br/>';
}
$buffer = ob_get_clean();
echo str_replace('<br/>', "\n", $buffer);
output
< more
> less
= equality
!= no't equality
which seems to be the correct behavoir.
It is important to understand how the
switch statement is executed in order
to avoid mistakes. The switch
statement executes line by line
(actually, statement by statement). In
the beginning, no code is executed.
Only when a case statement is found
with a value that matches the value of
the switch expression does PHP begin
to execute the statements. PHP
continues to execute the statements
until the end of the switch block, or
the first time it sees a break
statement.
http://de.php.net/manual/de/control-structures.switch.php
';
break;
case $page > 123:
echo '> less ';
break;
case $page == 99:
echo '= equality ';
break;
case $page != 99:
echo '!= no\'t equality ';
break;
default: echo 'Default';
}
?>
I'd like to to some thing similar to JavaScript's
var foo = true;
foo && doSometing();
but this doesn't seem to work in PHP.
I'm trying to add a class to a label if a condition is met and I'd prefer to keep the embedded PHP down to a minimum for the sake of readability.
So far I've got:
<?php $redText='redtext ';?>
<label class="<?php if ($requestVars->_name=='')echo $redText;?>labellong">_name*</label>
<input name="_name" value="<?php echo $requestVars->_name; ?>"/>
but even then the IDE is complaining that I have an if statement without braces.
use the ternary operator ?:
change this
<?php if ($requestVars->_name == '') echo $redText; ?>
with
<?php echo ($requestVars->_name == '') ? $redText : ''; ?>
In short
// (Condition)?(thing's to do if condition true):(thing's to do if condition false);
You can use Ternary operator logic
Ternary operator logic is the process of using "(condition)? (true return value) : (false return value)" statements to shorten your if/else structures. i.e
/* most basic usage */
$var = 5;
$var_is_greater_than_two = ($var > 2 ? true : false); // returns true
Something like this?
($var > 2 ? echo "greater" : echo "smaller")
I like to use the minimalist PHP text output syntax:
HTML stuff <?= $some_string ?> HTML stuff
(This works the same as using an <?php echo $some_string; ?>)
You can also use the ternary operator:
//(condition) ? (do_something_when_true) : (do_something_when_false);
($my_var == true) ? "It's true" : "It's false ;
Ending up like this:
<?= ($requestVars->_name=='') ? $redText : '' ?>
Sample Usage
Here are a couple more uses of ternary operators, ranging from simple to advanced:
Basic Usage:
$message = 'Hello '.($user->is_logged_in() ? $user->get('first_name') : 'Guest');
Short hand Usage:
$message = 'Hello '.($user->get('first_name') ?: 'Guest');
Echo Inline
echo 'Based on your score, you are a ',($score > 10 ? 'genius' : 'nobody');
A bit Tougher
$score = 10;
$age = 20;
echo 'Taking into account your age and score, you are: ',($age > 10 ? ($score < 80 ? 'behind' : 'above average') : ($score < 50 ? 'behind' : 'above average')); // returns 'You are behind'
complicated level
$days = ($month == 2 ? ($year % 4 ? 28 : ($year % 100 ? 29 : ($year %400 ? 28 : 29))) : (($month - 1) % 7 % 2 ? 30 : 31)); //returns days in the given month
To learn more about ternary operators and usage, visit PHP.net Comparison Operators or here.
Use ternary operator:
echo (($test == '') ? $redText : '');
echo $test == '' ? $redText : ''; //removed parenthesis
But in this case you can't use shorter reversed version because it will return bool(true) in first condition.
echo (($test != '') ?: $redText); //this will not work properly for this case
Ill provide with an other answer since the original question specifies the use of if() in html
<a class="menu-item" href="/about-us"><?= (pll_current_language() == 'en') ? 'About us' : 'Om oss' ?></a>
The provided answers are the best solution in your case, and they are what I do as well, but if your text is printed by a function or class method you could do the same as in Javascript as well
function hello(){
echo 'HELLO';
}
$print = true;
$print && hello();
I am trying to convert the following code into a Ternary Operator, but it is not working and I am unsure why. I think my problem is that I do not know how to express the elseif operation in ternary format. From my understanding and elseif is performed the same way as an if operation by using the format : (condition) ? 'result'.
if ($i == 0) {
$top = '<div class="active item">';
} elseif ($i % 5 == 0) {
$top = '<div class="item">';
} else {
$top = '';
}
$top = ($i == 0) ? '<div class="active item">' : ($i % 5 == 0) ? '<div class="item">' : '';
$top = ($i == 0) ? '<div class="active item">' : (($i % 5 == 0) ? '<div class="item">' : '');
you need to add parenthesis' around the entire else block
The Ternary Operator doesn't support a true if... else if... else... operation; however, you can simulate the behavior by using the following technique
var name = (variable === 1) ? 'foo' : ((variable === 2) ? 'bar' : 'baz');
I personally don't care for this as I don't find it more readable or elegant. I typically prefer the switch statement.
switch (variable) {
case 1 : name = 'foo'; break;
case 2 : name = 'bar'; break;
default : name = 'bas'; break;
}
Too late probably to share some views, but nevertheless :)
Use if - else if - else for a limited number of evaluations. Personally I prefer to use if - else if - else when number of comparisons are less than 5.
Use switch-case where number of evaluations are more. Personally I prefer switch-case where cases are more than 5.
Use ternary where a single comparison is under consideration (or a single comparison when looping), or when a if-else compare is needed inside the "case" clause of a switch structure.
Using ternary is faster when comparing while looping over a very large data set.
IMHO Its finally the developer who decides the trade off equation between code readability and performance and that in turn decides what out of, ternary vs. if else-if else vs. switch-case, can be used in any particular situation.
//Use this format before reducing the expression to one liner
$var=4; //Change value to test
echo "Format result: ";
echo($var === 1) ? 'one' : //if NB.=> $varname = || echo || print || var_dump(ternary statement inside); can only be (placed at the start/wrapping) of the statement.
(($var === 2) ? 'two' : //elseif
(($var === 3) ? 'three' : //elseif
(($var === 4) ? 'four' : //elseif
'false' //else
))); //extra tip: closing brackets = totalnumber of conditions - 1
// Then echo($var === 1)?'one':(($var === 2)?'two':(($var === 3)?'three':(($var === 4)?'four':'false')));
echo "<br/>";
var_dump("Short result: ", ($var === 1)?'one':(($var === 2)?'two':(($var === 3)?'three':(($var === 4)?'four':'false'))) );
I am trying to say $level > -100 && $level < 100
$level = 0;
switch($level){
case $level > -100:
break;
case $level < 100:
break;
default:
echo '5';
return null;
}
can you use a switch statement like this.
None of the answers presented so far have explicitly connected the spirit of the original question with a proper switch construction. So, for the record:
switch (true) {
case (($level>-100) && ($level<100)):
echo 'in range one';
break;
case (($level>200) && ($level<300)):
echo 'in range two';
break;
default:
echo 'out of range';
}
There's absolutely nothing wrong with this usage of switch.
When you say switch ($level) you're already comparing the value of $level. Each case can then only check for equality, you can't do comparisons like in your example. You'll have to use an if statement instead:
if ($level > -100 && $level < 100)
; // do nothing; equivalent of break in this case
else
echo '5';
Even simpler, just negate the conditions:
if ($level <= -100 || $level >= 100)
echo '5';
Apart of if/else, another way to do it:
switch (true)
case $level > -100:
break;
case $level < 100:
break;
default:
echo '5';
return null;
}
The other answers are both correct and incorrect at the same time. Incorrect, in that it is possible to do what you want in PHP... change switch($level) to switch(true) and your example will work. Correct, in that it's bad form and if any other programmers see that in your code they'll probably come after you with pitchforks. Its not how the switch statement is intended to be used, and wouldn't work like that in most other languages.
No you can't. Switch does only 'equals' type comparison.
No, you can't. The switch statement needs literals in the case blocks. Use an if statements instead:
if(!($level > -100 && $level < 100))
{
echo '5';
return null;
}
This is one of the reasons people advocating case as a superior solution to if-else are off base. I don't like the syntax or the limitations - if-ifelse-else is much more useful.