Advice on cleaner way to write this While statement - php

So the following code works, it is doing everything i want it to do. However, as i step back it seems like an overly convoluted approach to what is arguably one of the most common tasks in php.
I know enough about php to figure out what most things are doing when i see them, and to create some rather ugly code like you will see below; however, the finer points evade me.
I was hoping that if someone had some free time, he/she could look this over and show me a more concise way to approach this.
<?php
$result = mysql_query('SELECT * FROM events');
$i = 1;
while ($row = mysql_fetch_assoc($result)) {
echo '<div id="item_gallery_s'.$i .'"'. 'class="fluid profileImgWrap goldDiagGrad">' .
'<div class="profile_name">' . $row['name'] . '<br /><span class="profile_date">' .
'<a href="http:#"
target="_blank"
title="some title">' . $row['place'] .
'</a></span></div><!-- DCD Diva Name -->' .
'<a rel="events[events]"
href="#">' .
'<div class="profile_banner">Custom Banner</div><!-- Banner -->' .
'<img src='.'"img/upload/'.$row['icon'].
'"' .
'alt="image description |'.$row['name'].
'"/>' .
'<!-- Photo --></a></div><!-- END #item_gallery_s'.$i .'-->';
$i++;
}?>

The loop itself is fine but you'll find varying opinions on the HTML-in-strings. For the past seven years I've encouraged my team to either use HTML with php tags or we rely on a full templating system:
<?php while ($row = mysql_fetch_assoc($result)): ?>
<div><?= $row['something'] ?></div>
<?php endwhile ?>
Though we have short tags enabled for even cleaner code. The benefit of this is that it's cleaner - less quotes, escaping problems, and IDEs will be able to syntax highlight the html. Most treat the html as string when it's inside quotes.

That's as "concise" as it gets.
You could not use an echo inside the while. And use php short tags.
while ($row = mysql_fetch_assoc($result)) {
?>
<?=$row['place'];?>
<?php
}
?>
Another way to "clean up", would be to use a template engine, but once again that would be just for the HTML part.
{place}
Good coding!

You can clean this up a bit by interspersing actual HTML, rather than simply echoing it:
<?php
$result = mysql_query('SELECT * FROM events');
$i = 1;
while ($row = mysql_fetch_assoc($result)) {
?>
<div id="item_gallery_s<?php echo $i; ?>" class="fluid profileImgWrap goldDiagGrad">
<div class="profile_name">
<?php echo $row['name']; ?>
<br />
<span class="profile_date"><?php echo $row['place']; ?></span>
</div><!-- DCD Diva Name -->
<a rel="events[events]" href="#"><div class="profile_banner">Custom Banner</div><!-- Banner -->
<img src="img/upload/<?php echo $row['icon']; ?>" alt="image description |<?php echo $row['name']; ?>"/><!-- Photo --></a>
</div><!-- END #item_gallery_s<?php echo $i; ?> -->
<?php
$i++;
}?>
Another option, depending on how much work like this you have to do, would be a full-blown template engine such as Smarty.

Here's how I would probably format this code (as a matter of personal style):
<?php
$result = mysql_query('SELECT * FROM events');
$i = 1;
while ($row = mysql_fetch_assoc($result)) {
echo
'<div id="item_gallery_s'.$i.'" class="fluid profileImgWrap goldDiagGrad">
<div class="profile_name">' . $row['name'] . '<br /><span class="profile_date">
<a href="http:#" target="_blank" title="some title">' . $row['place'] .
'</a></span>
</div><!-- DCD Diva Name -->
<a rel="events[events]" href="#">
<div class="profile_banner">Custom Banner</div><!-- Banner -->
<img src="img/upload/' . $row['icon']. '"
alt="image description |' . $row['name']. '"/>
<!-- Photo -->
</a>
</div><!-- END #item_gallery_s'.$i .'-->';
$i++;
}
?>
Try also to use consistent indentation to make it easy to tell what matches up with what. By the way, a <div> (block element) inside an <a> (inline element) is bad form. Did you mean to use a <span>? Learn to use the W3C validator to pick up this stuff.

Related

Need to loop a block of code using while loop

The content is comming from a query and I dont whant to manually generate a long and repetitive block of code, so I thoght it would work nice if I put the first chunk into a while loop but, nothing good comes out of it.
Here is what I got so far...
<?php
$bloq_1 = array(1,2,3,4,5,7,8,9,10);
$blnu_1 = '1';
while( $bloq_1=$numeral_1) {
echo $numeral_1="<article class=\"notxtras\">
<a class=\"notxtras_url_cntn\" href=\"cdn.php?".$tema_s[$blnu_1++]['pltfrm']."=".$tema_s[$blnu_1++]['notid']."\" title=\"".$tema_s[$blnu_1++]['ttl']."\">
<div class=\"notxtras_img_cntn\">
<img src=\"http://cadenanoticias.mx/img/miniatura/".$tema_s[$blnu_1++]['pic1'] ."\" alt=\"".$tema_s[$blnu_1++]['rlcn'] ."\">
</div>
<h1 class=\"notxtras_ttl_cntn\">".$tema_s[$blnu_1++]['ttl']."</h1>
<p class=\"notxtras_brv_cntn\">".$tema_s[$blnu_1++]['brv'] ."</p>
<p class=\"notxtras_dsp_cntn\">Por: ".$tema_s[$blnu_1++]['aut'] ." • ".$tema_s[$blnu_1++]['cdd']." • ".ucfirst(strftime("%A %e de %B del %Y",date(strtotime($tema_s[$blnu_1++]['fch'])))) ."</p>
</a>
</article>";
}
?>
Is it posible?
I have three suggestions/comments:
If the content comes from a query, it would probably be better to use foreach to iterate over the actual query results (which appear to be stored in $tema_s), rather than iterating over a range of numbers. I don't know exactly how $tema_s is populated, but if it's like most other query results I've seen, you're probably missing item 0 if you use [1,2,3,4,5,7,8,9,10]. If you're doing this in order to only show ten results, it would be much better to add a LIMIT clause to your query so you won't be fetching more data than you need.
In cases where you find yourself echoing lots of HTML, it may be better to exit from PHP to produce the HTML, and just echo values from PHP where you need them. This will prevent the annoyance of escaping all those quotes, and the mess it will create when you miss one (not saying you have in this case, but it's quite easy to do.)
None of your variables have been properly escaped for HTML output.
Adjusting the code according to these ideas would be something like this:
<?php
foreach ($tema_s as $item):
$query_string = urlencode($item['pltfrm']. '=' .$item['notid']);
$title = htmlspecialchars($item['ttl']);
$src = urlencode($item['pic1']);
$alt = htmlspecialchars($item['rlcn']);
$date = ucfirst(strftime("%A %e de %B del %Y", date(strtotime($item['fch']))));
?>
<article class="notxtras">
<a class="notxtras_url_cntn" href="cdn.php?<?= $query_string ?>" title="<?= $title ?>">
<div class="notxtras_img_cntn">
<img src="http://cadenanoticias.mx/img/miniatura/"<?= $src ?>" alt="<?= $alt ?>">
</div>
<h1 class="notxtras_ttl_cntn"><?= $title ?></h1>
<p class="notxtras_brv_cntn"><?= htmlspecialchars($item['brv']) ?></p>
<p class="notxtras_dsp_cntn">
Por: "<?= htmlspecialchars($item['aut']) ?>
• <?= htmlspecialchars($item['cdd']) ?>
• <?= $date ?>
</p>
</a>
</article>";
<?php endforeach; ?>
Also, as mentioned in the comments on your question, you should consider looking into a template system, such as twig. It may seem like overkill for what you're doing here, but it takes care of a lot of this kind of stuff for you.
This should work:
<?php
$bloq_1 = array(1, 2, 3, 4, 5, 7, 8, 9, 10);
foreach ($bloq_1 as $blnu_1) {
echo "<article class=\"notxtras\">
<a class=\"notxtras_url_cntn\" href=\"cdn.php?" . $tema_s[$blnu_1]['pltfrm'] . "=" . $tema_s[$blnu_1]['notid'] . "\" title=\"" . $tema_s[$blnu_1]['ttl'] . "\">
<div class=\"notxtras_img_cntn\">
<img src=\"http://cadenanoticias.mx/img/miniatura/" . $tema_s[$blnu_1]['pic1'] . "\" alt=\"" . $tema_s[$blnu_1]['rlcn'] . "\">
</div>
<h1 class=\"notxtras_ttl_cntn\">" . $tema_s[$blnu_1]['ttl'] . "</h1>
<p class=\"notxtras_brv_cntn\">" . $tema_s[$blnu_1]['brv'] . "</p>
<p class=\"notxtras_dsp_cntn\">Por: " . $tema_s[$blnu_1]['aut'] . " • " . $tema_s[$blnu_1]['cdd'] . " • " . ucfirst(strftime("%A %e de %B del %Y", date(strtotime($tema_s[$blnu_1]['fch'])))) . "</p>
</a>
</article>";
}

Content showing PHP

I have a problem in a file : movies.php
I want to show all movies on the files when there is no id, and if the id exists, i want to show the movie with that id , i used :
echo "<div id='head'>$title</div>";
echo "<div id='bodyar'>$content</div> <br />
<hr>Category : <span class='date'>$moviecategory</span></hr>
<hr>Views : <span class='date'>$views_numimg</span></hr>
<hr></hr> <br />"; exit;}
$orderposts = mysql_query("select * from movie ");
echo "<div class='bodypanelposts'>";
while ($rowar = mysql_fetch_assoc($orderposts)) {
$id_po = $rowar['id'];
$picture = $rowar['picture'];
$title = $rowar['title'];
echo "<div id='movieall'><table id='classing' border='0'
cellspacing='2'><tr> <td>";
echo "<a href='movies.php?id=$id_po'><img src='$picture' alt='$image_caption' width='180' height='250'><br /></div><div class='movies'>$title</div></a><br />LIKE BOX GOES HERE</tr></td></table></div>";
}
The problem is , after using that , the footer is not appearing anymore ..
I want it to appear.
To let PHP know it has to start interpret the code, you need start tags:
<?php
// PHP code here
?>
You should also concat variables by a dot instead of putting into the quotes:
echo "<div id='head'>" . $title . "</div>";
(Some might say this is not important but it is IMO, PHP can't handle it properly in every case.)
When using exit;, you tell PHP to quit and flush the result to the browser.
There is also a closing } bracket after the exit, but I don't see any opening { bracket.
A better way to handle your HTML is to do it like this:
<div id='head'><?=$title?></div>
<div id='bodyar'><?=$content?></div>
<br />
<table>
<tr><td>Category</td><td><span class='date'><?=$moviecategory?></span></td></tr>
<tr><td>Views</td><td><span class='date'><?=$views_numimg?></span></td></tr>
</table>
<div class='bodypanelposts'>
<?php
while ($rowar = mysql_fetch_assoc($orderposts)) {
$id_po = $rowar['id'];
$picture = $rowar['picture'];
$title = $rowar['title'];
echo <<<HTML
<div id='movieall'>
<table id='classing' border='0' cellspacing='2'>
<tr><td><a href='movies.php?id=$id_po'><img src='$picture' alt='$image_caption' width='180' height='250'><div class='movies'>$title</div></a>
<br />LIKE BOX GOES HERE
</td></tr>
</table>
</div>
HTML;
?>
</div>
Notice the <?= tags to do inline PHP echo statements, allowing you to write HTML without having to wrap them in echo statements.
You can also use HEREDOC syntax to echo out a large chunk of HTML with variables inline.
These two methods make it much easier to reason about what your code is outputting.

PHP+HTML Syntax

I am trying to get a webpage to display four divs that will hold an img and a description. I would like to use a loop because I will have other pages with many of these divs. Here is the code I am using now:
for ($i=0;$i<4;$i++)
{
echo '<div class="item">
<img src="IMGs\\' . $items[$i]["ImgFilename"] . '" />
<h6 class="panel">Description</h6>
</div>';
}
I believe the problem is that I am not escaping the correct way. I have been searching for a while but cannot find the right combination. Files are stored in IMGs\file.jpg where file.jpg is pulled from the array.
Your escaping seems fine to me. However, I think the problem is with the double backslash. Eg, remove the \\ and replace it with / So that line becomes:
<img src="IMGs/' . $items[$i]["ImgFilename"] . '" />
U dont need to escape this.
change this:
<img src="IMGs\\' . $items[$i]["ImgFilename"] . '" />
to <img src="IMGs/' . $items[$i]["ImgFilename"] . '" />
You can lay that code out a little better by breaking in/out of PHP as required, here's a quick example:-
<?php for($index = 0; $index < 4; $index++): ?>
<div class="item">
<img src="IMGs/<?php echo $items[$index]["ImgFilename"]; ?>" />
<h6 class="panel">Description</h6>
</div>
<?php endfor; ?>

Show first 5 items in list, hide/toggle display of others (PHP)

I'd like to show the first 5 names in a list and toggle the display of any additional names as a single block.
I've currently got the names list as an array object though I'm happy to change it to an array if the solution would be simpler with that.
Here's what I have so far which is *in*complete because I don't know how to create the hidden div of names:
PHP
$names_count=0;
echo '<div id='nameList' class='toggler'>';
foreach($names as $name){
echo '<a id='name'.$name->acct_id.'>'.$name->full_name.'</a>';
if($names_count<=4){
echo '</div><!--toggler div-->';
}
else
<div class='namesList' style='display:none'>
//put additional names in hidden div?
</div>
}
$names_count++;
} //endforeach
JS:
UPDATE Sorry for the confusion. This isn't really a javascript question so I deleted that tag but I'm including the following jQuery code snippet for completeness with the PHP
$('.toggler').click(function(){
var id=this.id;
$('#'+id).toggle();
});
PHP
$names_count = 0;
echo '<div id="nameList" class="toggler">';
foreach($names as $name) {
echo '<a id="name' . $name->acct_id . '">' . $name->full_name . '</a>';
if ($names_count == 4) {
echo '</div><div class="hidden">';
}
$names_count++;
}
echo '</div>';
JS
$('.toggler').click(function(){
$(this).next().toggle();
});
CSS
.hidden {
display: none;
}
Here's an example with two while loops.
$names = array('Bob', 'Andy', 'Tim', 'Max', 'Roger', 'John', 'Test');
$nameCount = count($names);
$nameIndex = 0;
echo '<div id="nameList" class="toggler">';
// Show the first 5 names.
while ($nameIndex < min(5, $nameCount)) {
$name = $names[$nameIndex++];
echo '<a id="name' . $name . '">' . $name . '</a>';
}
// Show the remaining names in a hidden div.
if ($nameIndex < $nameCount)
{
echo '<div class="hiddenNames" style="display:none">';
while ($nameIndex < $nameCount) {
$name = $names[$nameIndex++];
echo '<a id="name' . $name . '">' . $name . '</a>';
}
echo '</div>';
}
echo "</div>";
That code produces the following output.
<div id="nameList" class="toggler">
<a id="nameBob">Bob</a>
<a id="nameAndy">Andy</a>
<a id="nameTim">Tim</a>
<a id="nameMax">Max</a>
<a id="nameRoger">Roger</a>
<div class="hiddenNames" style="display:none">
<a id="nameJohn">John</a>
<a id="nameTest">Test</a>
</div>
</div>
It also safe if you have less than 5 names; the script would produce :
<div id="nameList" class="toggler">
<a id="nameBob">Bob</a>
<a id="nameAndy">Andy</a>
<a id="nameTim">Tim</a>
</div>
For the JS, I would probably do something along the lines of :
$('.toggler').click(function(){
$('.hiddenNames').toggle();
});
Even if the code is a bigger, I find it easier to follow and probably easier to maintain in the long run. (Opinion)
Hope this helps!
To make a <div> hidden:
<div style="display: hidden"></div>
Then the jQuery should make it visible with the .toggle() command.

php order by 'most recent' 'most liked' 'least like'

I have a post system in place
<?php
/**
Display the results from the database
**/
$q = ("SELECT * FROM threads ORDER BY posted");
$r = mysql_query($q);
if(mysql_num_rows($r)>0): //table is non-empty
while($row = mysql_fetch_assoc($r)):
$net_vote = $row['votes_up'] - $row['votes_down']; //this is the net result of voting up and voting down
?>
<div class='entry'>
<span class='link'>
<?php echo $row['author']; ?>
<?php $row['posted'] = date("jS M Y h:i",$row['posted']); echo $row['posted']; ?>
<a href="http://twitter.com/share" class="twitter-share-button" data-count="horizontal" data-text="<?php echo $row['message']; ?>">
Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>
<br/>
<div class='message'><?php echo $row['message']; ?><br/></div>
<?php echo "<a href='msg.php?id=$row[id]'/> Comments/Add comments $row[replies]</a>" ?>
<?php echo "Likes: " . $row['votes_up'] . "&nbsp "; echo "Dislikes: " . $row['votes_down'] . "&nbsp"; ?>
</span>
<span class='votes_count' id='votes_count<?php echo $row['id']; ?>'></span>
<span class='vote_buttons' id='vote_buttons<?php echo $row['id']; ?>'>
<a href='javascript:;' class='vote_up' id='<?php echo $row['id']; ?>'></a>
<a href='javascript:;' class='vote_down' id='<?php echo $row['id']; ?>'></a>
<br/>
</span>
</div>
<br/>
<?php
endwhile;
endif;
?>
I want to add text that says 'order by : Most recent | Most liked | least liked '
As you can see i think ive got it already posting most recent by defualt which is what i want.
But what i want also is when you click 'Most liked' & 'least liked' it sorts by 'Vote_up' ( likes) & 'vote_down' (dislikes) all on the same page and shows posts with most likes on them (most liked) and most dislike (least liked)
EDIT***
sorry my question is how can i add 2 functions that when on click sorts by 'most liked' and 'least liked'
in html:
<a href='script.php?order=recent'>Recent</a>
<a href='script.php?order=liked'>Liked</a>
...
in php:
if ($_GET['order'] == 'recent') $order = "posted";
elseif ($_GET['order'] == 'liked') $order = "smth";
...
$q = "SELECT * FROM threads ORDER BY ".$order."";
but actually it's better to use some js framework (i prefer extjs for that) to sort the output on client side
AFAIK you have few choices how to do this:
Have the links pass a $_GET value via URL (causes a page refresh!!), then test for this in the PHP and run the necessary SQL to get the new record order.
Use AJAX to perform the same request asynchronously, with a PHP script to handle the SQL function and return the desired results.
Use a jQuery plugin such as tablesorter to (probably) basically provide the same functionality as that in 2, or via it's own filtering system -- I'm not sure i've not used it!!
My preference would be 1. (i.e a pure PHP + MySQL solution) as this offers the best universal functionality. You could always add javascript / ajax later to make things more swish for more modern browsers and users!

Categories