I'm programming in PHP, I'm using a 'shorthand if' to echo some HTML code on to the page, but it is behaving in odd ways.
echo '<div id="filter_bar">
<ul>';
echo '<li>Trending</li>' : '>Trending</a></li>';
echo '<li>Most Picked</li>' : '>Most Picked</a></li>';
echo '<li>Newest</li>' : '>Newest</a></li>';
echo '</ul></div>';
The resulting code that I get as a result is this
class="filter_selected">Trending</a></li> class="filter_selected">Most Picked</a></li> class="filter_selected">Newest</a></li>
As you can see, the opening list tags are not showing... but they do if I replace the first period '.' on each line with a ',' comma.
So this works, with the commas
Should I be using a comma here? Everywhere online sheems to show a period '.'
The reason is:
echo '<li>' . true ? 'aaa' : 'bbb'; will give you aaa,
because it is same with '<li>1' ? 'aaa' : 'bbb'
And you should do like this:
echo '<li>' . (true ? 'aaa' : 'bbb');
Maybe you can make your life a bit easier:
echo '<div id="filter_bar"><ul>',
'<li>' : '>', 'Trending</li>',
'<li>' : '>', 'Most Picked</li>',
'<li>' : '>', 'Newest</li>',
'</ul></div>';
Which will use commas (no need to repeat echo that much) and you don't need to repeat strings that much if you only want to insert the class attribute.
Then you made use of parenthesis where they were not needed (see Operator Precedence Docs) but at the place where those are needed, you didn't use them (the last case).
Additionally it's better to fill those values to variables upfront, so you can debug stuff easier (and you don't mix $_GET with output, so to prevent mixing output logic with input variables).
That done you could have learned that your issue is not within the echo but just the expression you've formulated with the ternary operator.
$class_trending = $_GET['select'] == "trending" ? ' class="filter_selected"' : '';
$class_most_picked = $_GET['select'] == "most_picked" ? ' class="filter_selected"' : '';
$class_newest = ($_GET['select'] == "newest") || empty($_GET['select']) ? ' class="filter_selected"' : '';
echo '<div id="filter_bar"><ul>',
'<li><a href="?select=trending"', $class_trending, '>Trending</a></li>',
'<li><a href="?select=most_picked"', $class_most_picked, '>Most Picked</a></li>',
'<li><a href="?select=newest"',$class_newest , '>Newest</a></li>',
'</ul></div>';
dunno your problem but this code looks an ugly mess for me.
I'd make it this way:
in the PHP code I'd prepare variables first.
$sections = array(
'newest' => 'Newest',
'trending' => 'Trending',
'most_picked' => 'Most Picked',
);
if (empty($_GET['select']) OR !$choice = array_search($sections,$_GET['select'])) {
$choice = 'newest';
}
and then in the template run smooth and short loop:
<div id="filter_bar">
<ul>
<? foreach ($sections as $sect => $name): ?>
<li>
<a href="?select=<?=$sect?><? if ($choice == $sect) ?>" class="filter_selected"<? endif ?>><?=$name?></a>
</li>
<? endforeach ?>
</ul>
</div>
One possible solution is
echo "<li><a href='?select=newest'";
echo ($_GET['select'] == "newest" || empty($_GET['select'])) ? ' class="filter_selected">Newest</a></li>' : '>Newest</a></li>';
Change your parentheses to the following:
echo '<div id="filter_bar">
<ul>';
echo '<li>Trending</li>' : '>Trending</a></li>');
echo '<li>Most Picked</li>' : '>Most Picked</a></li>');
echo '<li>Newest</li>' : '>Newest</a></li>');
echo '</ul></div>';
If you do not do this, PHP does not know what exactly your condition is. Also have a look at operator precendence as this explains why it works using commas.
By the way: The ?: is called ternary operator.
Related
In yang config I a have some parameter like:
$application_promo_shipping = true;
$application_promo_engrave = false;
I make PHP code with a ternary condition like this:
<p class="mx-auto nav-link-promo <?= ($this->config->item('application_promo_shipping')?:"d-none")?>">Free Shipping</p>
<p class="mx-auto nav-link-promo <?= ($this->config->item('application_promo_engrave')?:"d-none")?>">Free engrave</p>
If the value is true the "d-none" class is hide so the only text show is Free shipping
But how can I make like that with 2 parameters, if shipping and engrave is true I want to call a paragraph like this:
FREE ENGRAVE & FREE shipping
Because with the code now, I have a lot of space between 1 paragraph to another paragraph if I change the value to true in 2 parameters.
To your main question here ...
You CAN use multiple operators in one ternary condition and it will look like this:
$output = ($var1 === true && ($var2 == 2 || $var3 == 3)) ? 'if true' : 'if false';
BUT i wouldn't recommend it in your case simply because your ternary condition would be one mega-long line very hardly understanable to other programmers. So, ... how would i solve it?
Just rename your configuration values to something more understandable and shorter :), then you can do your ternary operation and the code will look good.
Approach no. 1:
<?php
$messages = [
0 => 'Free Shipping',
1 => 'Free engrave',
2 => 'FREE ENGRAVE & FREE shipping'
];
$shipping = $this->config->item('application_promo_shipping');
$engrave = $this->config->item('application_promo_engrave');
$message_key = ($shipping && $engrave) ? 2 : (($engrave) ? 1 : 0);
?>
<p class="mx-auto nav-link-promo"><?php echo $messages[$message_key]; ?></p>
Approach no. 2: (not recommended)
<?php
$shipping = $this->config->item('application_promo_shipping');
$engrave = $this->config->item('application_promo_engrave');
?>
<p class="mx-auto nav-link-promo <?php echo ($shipping) ? '' : 'd-none'; ?>">Free Shipping</p>
<p class="mx-auto nav-link-promo <?php echo ($engrave) ? '' : 'd-none'; ?>">Free engrave</p>
<p class="mx-auto nav-link-promo <?php echo ($shipping && $engrave) ? '' : 'd-none'; ?>">FREE ENGRAVE & FREE shipping</p>
One way of going about it is creating the output based on the two variables and store it in a variable that is an array. If the length is at least 1 or higher, print the paragraph and implode() the values with the deliminator &. This way, the paragraph doesn't even get rendered in HTML if both conditions are false.
Using shorter code by ternary operators can be useful - but in this case, it can probably be better to not render the output at all if the condition is true by using a normal if statement.
$output = [];
if ($this->config->item('application_promo_shipping')) {
$output[] = "Free shipping";
}
if ($this->config->item('application_promo_engrave')) {
$output[] = "Free engraving";
}
if (count($output)) {
?>
<p class="mx-auto nav-link-promo"><?php echo implode(" & ", $output); ?></p>
<?php
}
If you're hell-bent on using a ternary and using the d-none class, you can do that as well with the same condition (but you will still need the first two if blocks to declare the values of $output).
<p class="mx-auto nav-link-promo <?= count($output) ?: 'd-none'; ?>"><?= implode(" & ", $output); ?></p>
I tend to use a much simpler approach in order to make my code readable to other developers. Nothing worse than having to decipher code where someone has tried to be unnecessarily clever.
I would do something like this:
if (application_promo_shipping AND !application_promo_engrave) {
echo '<p class="mx-auto nav-link-promo">Free Shipping</p>';
}
if (application_promo_engrave AND !application_promo_shipping) {
echo '<p class="mx-auto nav-link-promo">Free Engraving</p>';
}
if (application_promo_engrave AND application_promo_shipping) {
echo '<p class="mx-auto nav-link-promo">Free Engraving</p> & <p class="mx-auto nav-link-promo">Free Shipping</p>';
}
I have a question about " and ' in PHP. I have to put a complete <li> element into a PHP variable but this doesn't work, the output is completely false...
$list =
"
<li class=\"<?php if($info[1] < 700) {echo \"half\";} else {echo \"full\";} ?>\">
<div class=\"onet-display\">
<?php if ($image = $post->get('image.src')): ?>
<a class=\"onet-display-block\" href=\"<?= $view->url('#blog/id', ['id' => $post->id]) ?>\"><img class=\"onet-thumb\" src=\"<?= $image ?>\" alt=\"<?= $post->get('image.alt') ?>\"></a>
<?php endif ?>
<h1 class=\"onet-thumb-title\"><?= $post->title ?></h1>
<div class=\"uk-margin\"><?= $post->excerpt ?: $post->content ?></div>
</div>
</li>
";
Is it because there is PHP Content in the HTML Code? How can I solve this?
Can someone help me and explain why this doesn't work?
<?php ... <?php
Since your string contains PHP tags, I suppose you expect them to be evaluated. The opening PHP tag within another PHP tag is interpreted as a part of the PHP code. For example, the following outputs <?php echo time();:
<?php echo "<?php echo time();";
There are several ways to build a PHP string from PHP expressions.
Concatenation
You can create functions returning strings and concatenate the calls to them with other strings:
function some_function() {
return time();
}
$html = "<li " . some_function() . ">";
or use sprintf:
$html = sprintf('<li %s>', some_function());
eval
Another way is to use eval, but I wouldn't recommend it as it allows execution of arbitrary PHP code and may cause unexpected behavior.
Output Buffering
If you are running PHP as a template engine, you can use the output control functions, e.g.:
<?php ob_start(); ?>
<li data-time="<?= time() ?>"> ...</li>
<?php
$html = ob_get_contents();
ob_end_clean();
echo $html;
Output
<li data-time="1483433793"> ...</li>
Here Document Syntax
If, however, the string is supposed to be assigned as is, use the here document syntax:
$html = <<<'HTML'
<li data-time="{$variable_will_NOT_be_parsed}">...</li>
HTML;
or
$html = <<<HTML
<li data-time="{$variable_WILL_be_parsed}">...</li>
HTML;
You want to store some html into a variable.
Your source should (if not yet) start with
<?php
Then you start building the contents of $list.
Starting from your code the nearest fix is to build $list by appending strings:
<?php
$list = "<li class=";
if($info[1] < 700)
{
$list .= "\"half\""; // RESULT: <li class="half"
}
else
{
$list .= "\"full\""; // RESULT: <li class="full"
}
// ...and so on...
Now a couple things to note:
$list .= "... is a short form of $list = $list . "...
Where the . dot operator joins two strings.
Second thing you may make code easier to read by mixing single and double quotes:
Use double quotes in PHP and single quotes in the generated HTML:
<?php
$list = "<li class=";
if($info[1] < 700)
{
$list .= "'half'"; // RESULT: <li class='half'
}
else
{
$list .= "'full'"; // RESULT: <li class='full'
}
// ...and so on...
This way you don't need to escape every double quote
i think you have to work like this
$test = "PHP Text";
$list = "<strong>here ist Html</strong>" . $test . "<br />";
echo $list;
I'm trying to add a class="active" statement to a dynamic li element based on if it's meets a requirement of a pageID being equal to a variable named thisPage but I have the syntax messed up. My problem is how do I add my if statement into the middle of a string? I think I have the spirit captured below....
Thanks
<? ...........
$menu .= "\t<li" . ' if $thisPage=={$pageID} echo class="active"' . ">{$pval['menuTitle']}</li>\n";
...........
?>
You can use a ternary
$menu .= '<li'.($thisPage==$pageID?' class="active"':'').'></li>';
Try this
$menu .= "\t<li".($thisPage==$pageID ? ' class="active"' : '').'>'.$pval['menuTitle'].'</li>'."\n";
Though I'd recommend using sprintf to make what's going on clearer
$menu .= sprintf('\t<li%s>%s</li>',
($thisPage==$pageID ? ' class="active"' : ''),
$pval['link'],
$pval['menuTitle']);
easiest way would be to use a ternary operator like this:
$menu .= "\t<li" . $thisPage=={$pageID} ? 'class="active"' : '' . ">{$pval['menuTitle']}</li>\n";
I am trying to echo out multiple table rows on my sql query and provide them with alternating colors to improve the aesthetic value of my site. I am fairly new to php and I am extremely fussy over the presentation of my code and therefore I would like to include the output html into my PHP block to improve readability.
I have browsed some past threads but I am still rather unclear of how the formatting of a string works in PHP, the code below shows my attempt of formatting the output:
echo '<tr class=" . 'if( $class_style %2 == 0 ){ echo "row_dark"; } else echo "row_light"' . ">';
What am I doing wrong here?
Regards
Alex.
You can't put an if structure in an echo.Use that :
echo '<tr class="'. ($class_style %2 == 0) ? 'row_dark' : 'row_light' . '">';
It's a ternary operation.
You should use like this right syntax:
echo '<tr class="'.($class_style %2 == 0 ? "row_dark" : "row_light").'">';
It should be
echo '<tr class=" '. instead of echo '<tr class=" .'
<?php echo '<tr class="'.(($class_style %2 == 0)?'row_dark':'row_light').'">';?>
or
<?='<tr class="'.(($class_style %2 == 0)?'row_dark':'row_light').'">';?>
I'm trying to do a simple task, insert a second function name under "onmouseover" but probably something is wrong with the syntax.
echo '<div onmouseover="changeText(); <?php if($title==""){echo changeViz();}; ?> ">';
I probably need to escape some quotes and add some, but i can't figure out the correct solution.
Thanks
Nothing it's working. Let me give you the complete code...:
echo '<div class="frame" onmouseover="changeText(\''.$text[$i].'\'); <?php if($title[$i]==""){echo changeViz();}; ?>">';
You are nesting <?php ?> inside existing php code, which is a syntax error. Instead, concatenate in the javascript function changeViz() as a quoted string.
This version uses a ternary operator to duplicate the if() statement you had originally.
echo '<div onmouseover="changeText(); ' . ($title == '' ? 'changeViz();' : '') . '">';
The ternary operation here will concatenate changeViz(); onto the echo string if $title == "", or otherwise just concatenate on an empty string.
Update after seeing full code:
You have the quote escaping correct in the first part.
echo '<div class="frame" onmouseover="changeText(\'' . $text[$i] . '\'); ' . ($title == '' ? 'changeViz();' : '') . '">';
You can make your code much more readable if you do not try to do everything in one line:
$onmouseover_action = "changeText(); ";
if($title==""){
$onmouseover_action .= "changeViz(); ";
}
echo '<div onmouseover="'.$onmouseover_action.'">';
It makes your code easier to maintain, and you have less need to comment it, because it describes itself quite much better.
Try this:
echo '<div class="frame" onmouseover="changeText(\''.$text[$i].'\'); '. ($title[$i]=="")?'changeViz();':'').'">';