Conventions for combining PHP with HTML - php

I am studying PHP from a book. The author uses echo to output HTML. At first I thought that this was how it supposed to be done, but then I picked up a more "advanced" book. The author of the second book inserted PHP code between HTML rather then echo the whole thing. How is it done in large web development companies that work on large projects? Can you use either, or is one more accepted than the other?
Take this code for example:
<?php
//pagination
if ($pages > 1) {
//determine the current page
$current_page = ($start / $display) + 1;
//print out Previous Page button
if ($current_page != 1) {
?>
<div class="pages"><strong> < </strong></div>
<?php
}
//print the page numbers
for ($i = 1; $i <= $pages; $i++) {
if ($i == $current_page) {
?>
<div class="pages active"><span> <?php echo $i; ?> </span></div>
<?php
}
else {
?>
<div class="pages"><strong> <?php echo $i; ?> </strong></div>
<?php
}//end of $i = $current_page conditional
}//end of FOR loop
if ($current_page < $pages) {
?>
<div class="pages"><strong> > </strong></div>
<?php
}
}//end of pagination
include('includes/footer.php');
?>
Is that the correct way of doing it, or should I use something like this:
echo '<a href="view_users.php?s=' . ($display * ($i - 1)) .
'&p=' . $pages . '&sort=' . $sort . '">' . $i . '</a> ';
The reason why I'm asking is because I find it difficult to properly align the HTML when using the second technique, and I don't want to develop any bad habits early on.

The first method makes your code more readable. The second method is useful when you need to print some little amount of html code. Also you can use short open tags to insert your php code between html tags. For example if you need to print language parameter of URL you can do like this:
<a href="index.php?lang=<?=$lang?>" >A Link</a>
This is equal to this:
<a href="index.php?lang=<?php echo $lang; ?>" >A Link</a>

I'd recommend using a good framework in general, and a templating engine for outputting pages. This way, your data models, your application logic, and your HTML are all kept separate.

This is a somewhat subjective question, but:
echo '<a href="view_users.php?s=' . ($display * ($i - 1)) .
'&p=' . $pages . '&sort=' . $sort . '">' . $i . '</a> ';
This is not very good, because it quickly becomes hard to read. It's the worst option to use IMO.
Here an evolution on how this can be improved:
<a
href="view_users.php?s=<?php echo $display * ($i - 1); ?>&p=<?php echo $pages; ?>&sort=<?php echo $sort; ?>">
<?php echo $i; ?>
</a>
<?php
printf('%i',
$display * ($i - 1), $pages, $sort, $i);
?>
<?php
$q = http_build_query(array(
's' => $display * ($i - 1),
'p' => $pages,
'sort' => $sort
));
?>
<?php echo $i; ?>
<?php
printf('%i',
http_build_query(array(
's' => $display * ($i - 1),
'p' => $pages,
'sort' => $sort
)),
$i);
?>

Paul, what you're looking at in that code is a combination of PHP, CSS and HTML. echo just means print on page and it is a PHP function which is why you see it with the tags.
<?php ?>
Does this answer your question?
Also PHP and HTML and CSS will not parse any whitespace so indenting is done to enhance readability. I suggest you comment your code and format it however it is easier for you to understand. From a professional standpoint check out the W3C validator for proper code formatting.

Both are acceptable really, using echo for short statements and completely breaking out of php for long bits of html. Indentation of your HTML doesn't matter that much, it just looks pretty when someone checks out your source.

wrapping html generation in functions and building output strings can be a good practice. That way you can have complex logic expressed in a readable way:
<?php
function get_pagination_html($pages, $start, $display) {
$html = "";
if ($pages <= 1) return $html;
$current_page = ($start / $display) + 1;
if ($current_page != 1) {
$previous = $start - $display;
$html .= "<div class='pages'><strong><a href='view_users.php?s={$previous}&p={$pages}'> < </a></strong></div>";
}
for ($page_number = 1; $page_number <= $pages; $page_number++) {
if ($page_number == $current_page) {
$html .= "<div class='pages active'><span> {$page_number} </span></div>";
} else {
$page_start = $display * ($page_number - 1);
$html .= "<div class='pages'><strong><a href='iew_users.php?s={$page_start}>&p={$pages}'> {$page_number} </a></strong></div>";
}
}
if ($current_page < $pages) {
$next = $start + $display;
$html .= "<div class='pages'><strong><a href='view_users.php?s={$next}&p={$pages}'> > </a></strong></div>";
}
return $html;
}
echo get_pagination_html($pages, $start, $display);
Notice how much easier it reads. You also don't need any comments because variable names are self explanatory

Related

How to make current page with different style (PHP ?page href)?

My piece of code.
And problem now are about styling, i just want style page number, wich is open, like a active id, if page open, then that number is in different color or smth else.
I need make a new variable? Or what, i just try to add but its wont work, it only works if at the end i write echo $page; , then it show style on this, but i need on links, numbers.
<?php
if($total_pages > 1){
if($page != 1){
echo ' < ';
}
for($number=1;$number<=$total_pages;$number++)
{
echo ''.$number.'';
}
if($page != $total_pages){
echo ' > ';
}
}
?>
You can do something like this.
$currentPageNumber = $_GET['page'];
for($number=1;$number<=$total_pages;$number++){
$currentPageStyle = '';
if($number == $currentPageNumber){
$currentPageStyle = 'style="color:red"';
}
echo '<a href="?page='.$number.'" '.$currentPageStyle.'>'.$number.'</a>';
}

Separate MySQL results into Divs using while loop

Just beginning PHP to bear with me.
Results I'm trying to achiever:
I have a table of YouTube URL's and MetaData.
Trying to build this:
<div class="slide">
<iframe></iframe>
<iframe></iframe>
</div>
<div class="slide">
<iframe></iframe>
<iframe></iframe>
</div>
Two videos per slide, then I'm going to paginate through results using Deck.js.
I suspect I'm going about this completely the wrong way, not that experienced at programmin g logic;
while($data = mysql_fetch_array($result)) {
for ($counter = 1; $counter<=2; $counter++) {
echo "<div class=\"slide\">";
echo "<h3>" . $data['VIDEO_TITLE'] . "</h3>";
echo "<iframe width=\"560\" height=\"315\" src=\"" . $data['VIDEO_URL'] . "\" frameborder=\"0\" allowfullscreen></iframe>";
/* If Video 1, increment counter for 2nd video */
if ($counter == 1) {
$counter++;
}
/* If Video 2, close div and reset counter */
else if ($counter == 2) {
echo "</div>";
$counter = 1;
}
/* If error break out */
else {
echo "</div>";
break;
}
}
}
Basically trying to nest loops to keep track of how many videos per div and start a new one when a div has two.
I've tried a few different ways, this being the latest. Results in:
<div class="slide">
<iframe></iframe>
<div class="slide>
<iframe></iframe>
Hit the blank wall now, not sure what to try next. Willing to use/learn any method to accomplish the results, just not sure where to go at this point.
Cheers.
You could remove the second loop all together using the % operator (modulus). The idea is that a % b === 0 then the number a was evenly divisible by b. Using this, you can easily check for even or odd or every Nth row.
$k = 1;
echo "<div class=\"slide\">";
while($data = mysql_fetch_array($result)) { // you should really change to mysqli or PDO
if($k % 3 === 0){
echo "</div>";
echo "<div class=\"slide\">";
}
echo "<h3>" . $data['VIDEO_TITLE'] . "</h3>";
echo "<iframe width=\"560\" height=\"315\" src=\"" . $data['VIDEO_URL'] . "\" frameborder=\"0\" allowfullscreen></iframe>";
$k++;
}
echo "</div>";
Put the echo <div> before the for loop (still inside the while loop) and the </div> after the for loop
In your while loop you're retrieving just one row, but then you're iterating over it twice with a nested loop. Do away with the inner loop and just use a flip-flop variable to track left and right. I think this will do what you want:
$left=true; // track whether we're emitting HTML for left or right video
while($data = mysql_fetch_array($result)) {
if ($left) {
echo "<div class=\"slide\">";
echo "<h3>" . $data['VIDEO_TITLE'] . "</h3>";
}
echo "<iframe width=\"560\" height=\"315\" src=\"" . $data['VIDEO_URL'] . "\" frameborder=\"0\" allowfullscreen></iframe>";
if (!$left) {
echo "</div>";
}
$left = !$left; // invert $left to indicate we're emitting the right iFrame
}
// end of loop. If we had an odd number of
// videos, tidy up the HTML
if (!$left) {
echo "</div>";
}
PHPFiddle
<?php
$x = 10;
$counter = 0;
while($x > 0)
{
if($counter != 0 && $counter % 2 == 0)
{
echo "ENDOFSLIDE</br>";
}
if($counter == 0 || $counter % 2 == 0)
{
echo "SLIDE</br>";
}
echo "iframe => $x </br>";
$x--;
$counter++;
}
echo "ENDOFSLIDE";
?>
It won't work because the for loop is inside the fetch loop for the SQL data. The second iteration of the for loop does not have a new SQL row. A better solution would be to capture the common column that identifies the two videos (the title) and generate a new div whenever that value changes. Try something like this, which will work for any number of SQL rows with the same title. This will also give proper results if the SQL query returns no rows and will handle the potential of a title with only one URL - which could get ugly if you merely flip-flop and end up with URLs on the wrong title. Of course, as in your current solution, your SQL query must ORDER BY VIDEO_TITLE so the rows are adjacent. I didn't run it, but should be close.
$lastTitle = "";
$n = 0; //count SQL rows processed
while($data = mysql_fetch_array($result)) {
// See if the title changed from last
if( $data['VIDEO_TITLE'] != $lastTitle ) {
// if we processed any rows, must end the current div before starting a new one
if( $n > 0 )
echo "</div>";
echo "<div class=\"slide\">";
echo "<h3>" . $data['VIDEO_TITLE'] . "</h3>";
//save the title as last title
$lastTitle = $data['VIDEO_TITLE'];
}
$n++; //count the SQL row
echo "<iframe width=\"560\" height=\"315\" src=\"" . $data['VIDEO_URL'] . "\" frameborder=\"0\" allowfullscreen></iframe>";
}
if( $n > 0 )
echo "</div>";

PHP Pagination Link Generation

I have this script below which i found on SO to generate pagination and broadly speaking, its working great, however because its a cut and paste job from me, i don't understand how to actually generate the links which are echoed in the script with the variable $pagination.
What it echos is:
1< a href="index.php?page=2">2< a href="index.php?page=3">3< a hr_ef="?page=2"> Next
None of which are working (clickable) links, and i also want to be able to style them so would rather output them in HTML, rather than a php echo, something like:
<p><?php 1< a href="index.php?page=2">2< a href="index.php?page=3">3< a hr_ef="?page=2"> Next ?> </p>
Below is the script i'm using:
<?php
/* Set current, prev and next page */
$page = (!isset($_GET['page']))? 1 : $_GET['page'];
$prev = ($page - 1);
$next = ($page + 1);
/* Max results per page */
$max_results = 10;
/* Calculate the offset */
$from = (($page * $max_results) - $max_results);
/* Query the db for total results.*/
$result = mysql_query("...");
$total_results = mysql_num_rows($result);
$total_pages = ceil($total_results / $max_results);
$pagination = '';
/* Create a PREV link if there is one */
if($page > 1)
{
$pagination .= '< a href="?page='.$prev.'">Previous</a> ';
}
/* Loop through the total pages */
for($i = 1; $i <= $total_pages; $i++)
{
if(($page) == $i)
{
$pagination .= $i;
}
else
{
$pagination .= '< a href="index.php?page='.$i.'">'.$i.'</a>';
}
}
/* Print NEXT link if there is one */
if($page < $total_pages)
{
$pagination .= '< a hr_ef="?page='.$next.'"> Next</a>';
}
/* Below is how you query the db for ONLY the results for the current page */
$query ="SELECT * FROM ... LIMIT $from, $max_results";
$result=mysql_query($query) or die(mysql_error());
$rsjobinfo=mysql_fetch_assoc($result);
do {?>
<div>
[Individual Row Output]
</div>
<?php } while ($rsjobinfo=mysql_fetch_assoc($result));
echo $pagination;
?>
Can someone help? I imagine its a small fix but as always, would appreciate a kick in the right direction.
Thanks
Dan
Maybe it's just an editing error, but in your output the <a>-tags don't seem to be closed again. Also, there should be no space like < a> at the beginning of the tag. And < a hr_ef= ... is obviously wrong.
In order to style them, you can add a class attribute to the tags while building the string and do the style-stuff in css.

how can I get these if statements working

i am trying to get my data from the database and wrap it with html tags. here is the working code so far:
function homethumb(){ $this->count; $i = 0;
while($row = mysqli_fetch_object($this->result))
{
$this->count++; $i++;
if($i == 1){echo '<div class="gal1">';}
echo ' <div class="gal"><img src="img/' . $row->thumb2 . '.jpg"></div>';
if($i == 2){
echo '</div> <!-- gal1 -->';
$i=0;
}
}
}
Here I am getting everything from the database (Select * from portfolio), but in the portfolio I have, websites, demos and graphics; so I wanted to get only the data where category = "web" from the above code, so I tried this:
function homethumb(){ $this->count; $i = 0;
while($row = mysqli_fetch_object($this->result))
{
if($row->category = "web"){
$this->count++; $i++;
if($i == 1){echo '<div class="gal1">';}
echo ' <div class="gal"><img src="img/' . $row->thumb2 . '.jpg"></div>';
if($i == 2){
echo '</div> <!-- gal1 -->';
$i=0;
}
}
}
}
now the nested if statements do not generate the divs I need, how can I get this working
thanks for your help
I can't see your SQL based on your question, but you could just modify your SELECT query to include WHERE category="web"
This way, you're only selecting the rows you need, instead of looping over every row in that table.
Additionally, it appears that you're using assignment = instead of comparison == for your if statement.
Do you just need to have == instead of =?
if($row->category == "web"){
But it would be best to restrict the query to the results you need at the database level, unless you need the other rows for some reason.
1)You missed an equal sign:
if($row->category = "web") => if($row->category == "web")
Or better yet
if($row->category === "web")
2)If you want to only get fields with a specific category field, you can simply change your query:
[rest of your query] WHERE category="web"
OK, it should go like this, assuming the fields are sorted as follows
ID, category, website, thumb2, demo, graphics
function homethumb(){ $this->count; $i = 0;
while($row = mysqli_fetch_object($this->result))
{
if($row[1] == "web"){
$this->count++; $i++;
if($i == 1){echo '<div class="gal1">';}
echo ' <div class="gal"><img src="img/' . $row[3] . '.jpg"></div>';
if($i == 2){
echo '</div> <!-- gal1 -->';
$i=0;
}
}
}
}
and there is no need for the nested if, you can just use it in one line as follows:
if($row[1] = "web")
{
echo '<div class="gal1">';
echo ' <div class="gal"><img src="img/' . $row[3] . '.jpg"></div>';
echo '</div> <!-- gal1 -->';
}
1) Change your query to contain a WHERE category="web" clause
2) You have an assignment operator in your if clause (=), when you need an equality operator (==)

How to make this code more readable

This is a part fo php code, which use the contentArray, which is a JSON, and generate the UI to the user, it generate html tags, also, it generate js code too.... It works, but I think the code is pretty difficult to read and maintain, any ideas??? thank you.
for($i = 0; $i < count($contentArray); $i++){
if($i %2 == 0){
echo ("<li class='even_row'>");
}else{
echo ("<li class='odd_row'>");
}
$content = $contentArray[$i];
echo("<textarea class='userdata' id='user_data_textarea_".$content->{'m_sId'}."'>");
echo($content->{'m_sDataContent'});
echo("</textarea>");
echo("</li>");
echo("<script type='text/javascript'>");
echo("$('#user_data_textarea_".$content->{'m_sId'}."').bind('keydown', function(e){");
echo(" TypingHandler.handleTypingInUserDataTextArea(".$content->{'m_sId'}.", e);");
echo(" });");
echo("</script>");
}
first for your odd and even styling there is not need for a class just use css
here is info on that
then in php only echo what you need in one line
$count = count($contentArray);
for($i = 0; $i < $count; $i++){
$content = $contentArray[$i];
echo('<li><textarea class="userdata" id="user_data_textarea_"'.$content->{'m_sId'}.'">'.$content->{'m_sDataContent'}.'</textarea></li>');
}
and lets put the jquery in the html page away from php
we get can get every item by using starts with selector
$('[id^=user_data_textarea_]').bind('keydown', function(e){
var id = this.id.str_replace("user_data_textarea","");
TypingHandler.handleTypingInUserDataTextArea(id, e);
});
One tip on your "for" loop, you should calculate the count of $contentArray before the loop. Every time the loop executes, it has to call that function.
$count = count($contentArray);
for ($i=0; $i<count; $i++) {
// ...
}
You could try real HTML:
<?php
for($i = 0; $i < count($contentArray); $i++){
$rowClass = $i %2 == 0 ?'even_row' : 'odd_row';
?>
<li class='<?= $rowClass ?>'>
<textarea class='userdata' id='user_data_textarea_<?=$content->{'m_sId'}?>'>
<?= $content->{'m_sDataContent'} ?>
</textarea>
</li>
<script type='text/javascript'>
//etc...
</script>
<?php } ?>
It should look something like this, for better readability in the IDE.
<?php
foreach($contentArray as $content){
?>
<li>
<textarea class="userdata" id="user_data_textarea<?php echo htmlentities($content['m_sId']); ?>">
<?php echo htmlspecialchars($content['m_sDataContent']); ?>
</textarea>
<script type="text/javascript">
$('#user_data_textarea_<?php echo htmlspecialchars($content['m_sId']); ?>').bind('keydown',function(e){
TypingHandler.handleTypingInUserDataTextArea('<?php echo htmlspecialchars($content['m_sId']); ?>',e);
});
</script>
</li>
<?php
}
You could remove the ( ) from the echo statements, they're not necessarily needed and might help make it look a little neater...
That actually looks pretty understandable to me; I could figure out what you're doing without difficulty. The only difference I would suggest would be the use of ternary operators for the row class:
echo "<li class='".( ($i%2 == 0) ? "even" : "odd" )."_row'>";
...but that's just me, some would find that MORE confusing, rather than less. I personally like putting it all in one line.
Personnaly, I like to use printf to write html code in php. It could look like:
for($i = 0; $i < count($contentArray); $i++){
printf("<li class='%s'>", $i % 2 ? "odd_row" : "even_row");
$content = $contentArray[$i];
printf("<textarea class='userdata' id='user_data_textarea_%s'>%s</textarea>",
$content->{'m_sId'},
$content->{'m_sDataContent'});
echo("</li>");
echo("<script type='text/javascript'>");
printf("$('#user_data_textarea_%1$s').bind('keydown', function(e){
TypingHandler.handleTypingInUserDataTextArea(%1$s, e);
});",
$content->{'m_sId'});
echo("</script>");
}
<?php
foreach($contentArray as $content){
$class = ($i %2 == 0) ? "even_row": "odd_row"; ?>
<li class="<?php echo $class ?>">
<textarea class='userdata' id='user_data_textarea_<? echo $content['m_sId'] ?>'>
<? php echo $content['m_sDataContent'] ?>
</textarea>
</li>
<script type='text/javascript'>
$('#user_data_textarea_<?php echo content['m_sId'] ?>').bind('keydown', function(e){
TypingHandler.handleTypingInUserDataTextArea(<?php $content['m_sId'] ?>, e);
});
</script>
<?php } // end foreach ?>
jQuery code should be already in the HTML, using some main selector and not binding elements one by one, it not makes sense for me. That should clarify your code.
for($i = 0; $i < count($contentArray); $i++){
$content = $contentArray[$i];
echo "<li class='" . (($i %2 == 0) ? "even_row" : "odd_row") . ">";
echo "<textarea class='userdata' id='user_data_textarea_".$content->{'m_sId'}."'>";
echo $content->{'m_sDataContent'};
echo "</textarea>";
echo "</li>";
}
ADDED
A generic case:
$(function() {
$('.userdata').click(function() {
some_function($(this).attr('id');
});
})
That is, bind using a class selector and late use some unique identifier for doing the job.
Put everything in arrays, then echo them at the END of your loop.
// Put each item in the array, then echo at the end
$items = array();
$js = array();
// I'm assuming that your content array has numeric keys
// if not, use the for statement from your original code
foreach ($contentArray as $i => $content)
{
// using sprintf
$items[] = sprintf('<li class="%s_row"><textarea class="userdata" id="user_data_textarea_%s">%s</textarea></li>'
, ($i % 2) ? 'even' : 'odd'
, $content->m_sId
, $content->m_sDataContent
);
// or just plain old concatenation
$js[] = "$('#user_data_textarea_{$content->m_sId}').bind('keydown', function(e){TypingHandler.handleTypingInUserDataTextArea({$content->m_sId}, e);});";
}
echo "<ul>" . join("\n", $items) . "</ul>\n"
. '<script type="text/javascript">' . join("\n", $js) . "</script>\n";
Separate your content and code using for example smarty. It requires some infrastructure investment in the short term, but improves maintenance in the long run.
Reflecting the comments, let's then treat PHP as a real templating language.
$contentCount = count($contentArray);
for($i = 0; $i < $contentCount; $i++)
{
$rowType = ( $i % 2 ) ? 'even' : 'odd';
$content = $contentArray[$i];
echo <<<EOT
<li class='{$rowType}_row'>
<textarea class='userdata' id='user_data_textarea_{$content->m_sId}'>
{$content->m_sDataContent}
</textarea>
</li>
<script type="text/javascript">
$('#user_data_textarea_{$content->m_sId}').bind('keydown', function(e)
{
TypingHandler.handleTypingInUserDataTextArea({$content->m_sId}, e);
}
</script>
EOT;
}

Categories