PHP - Unable to get same number of </ul> as <ul> - php

I am unable to generate same number of </ul> as <ul> in the following code:
<?php
$array=array("item1","item2","item3");
for ($i=0;$i<count($array);$i++)
{
if($i<count($array)-1)
{
echo '<li><span>'.$array[$i].'</span><ul>';
}
else
{
echo '<li><span>'.$array[$i].'</span>';
}
}
for ($i=0;$i<count($array);$i++)
{
echo '</ul></li>';
}
?>
The code is generating uneven number of <li><ul> and </ul></li>. Please tell me where I am going wrong?

This is a minor error. In your second for statement change $i<count($array); to $i<count($array)-1;.
So your final code will be:
<?php
$array=array("item1","item2","item3");
for ($i=0;$i<count($array);$i++)
{
if($i<count($array)-1)
{
echo '<li><span>'.$array[$i].'</span><ul>';
}
else
{
echo '<li><span>'.$array[$i].'</span>';
}
}
for ($i=0;$i<count($array)-1;$i++)
{
echo '</ul></li>';
}
?>

With if($i<count($array)-1) you check if $i is smaller than the length - 1.
That check isn't performed in the second loop. So the first one actually performs as many steps as the second one but only writes in all but the last iteration.

Try This:
$array=array("item1","item2","item3");
echo '<ul>';
for ($i=0;$i<count($array);$i++)
{
echo '<li><span>'.$array[$i].'</span></li>';
}
echo '</ul>;

Related

PHP Recordset and EOF

I feel like I know this, but am getting frustrated that I can't remember exactly how to do this.
In PHP, I need to repeat items of a record set in a unordered list. I can repeat items fine, but I don't want anything to show if the record set is empty. Right now, if there is no record, the code is still displaying a blank list item, when I just want nothing to appear.
I have tried this:
<?php do { ?>
<li>Content Goes Here</li>
<?php } while (!feof($recordsetName) && $row_recordsetName = mysql_fetch_assoc($recordsetName)); ?>
And I have tried doing it this way by putting the repeating element withing an if/else statement like this:
<?php if (!feof($recordsetName)) {
echo ""; }
else do { ?>
<li>Content Goes Here</li>
<?php } while ($row_recordsetName = mysql_fetch_assoc($recordsetName));
; } ?>
But that isn't working either. Any information would be helpful
while($row = mysql_fetch_assoc($recordsetName)) {
if($row['fieldname'] != '') {
echo '<li>Content Goes Here</li>';
}
}
or you could check if the query was successful...
$result = mysql_query($sql);
if($result) {
echo '<li>Content Goes Here</li>';
}
or if it returned any results...
$results = mysql_fetch_assoc($recordsetName);
if(mysql_num_rows($results) > 0) {
while($row = mysql_fetch_assoc($results)) {
echo '<li>Content Goes Here</li>';
}
}
Also, you should really be using mysqli or PDO, as mysql is depreciated.
Edit: added loop in example 3.

How to speedup by code?

is there a way to speed up my code? It takes about 15 seconds to load ... I don't really see a way to reduce my code... I just thought about inserting the values into database, so the user does not have to load new info every time.. but the thing is that my cron only allows 1 load per hour ... by loading new info on every load it gives me fresh information..
$q1=mysql_query("SELECT * FROM isara");
while($r1=mysql_fetch_array($q1)){
$named=$r1['name'];
$idd=$r1['id'];
$descd=$r1['desc'];
$online=check_online($named);
$char = new Character($r1['name'],$r1['id'],$r1['desc']);
if($online == "online"){
$char->rank = $i++;
}
else{
$char->rank = 0;
}
$arr[] = $char;
}
?>
<br />
<h2 style="color:green">Online enemies</h2>
<?php
foreach ($arr as $char) {
if($char->rank>=1){
echo "<a style=\"color:green\" href=\"http://www.tibia.com/community/?subtopic=characters&name=$char->name\">";
echo $char->name." ";
echo "</a>";
echo level($char->name)."<b> ";
echo vocation($char->name)."</b> (<i>";
echo $char->desc." </i>)<br />";
}
}
?>
<br />
<h2 style="color:red">Offline enemies</h2>
<?php
foreach ($arr as $char) {
if($char->rank==0){
echo "<a style=\"color:red\" href=\"http://www.tibia.com/community/?subtopic=characters&name=$char->name\">";
echo $char->name." ";
echo "</a>";
echo level($char->name)."<b> ";
echo vocation($char->name)."</b> (<i>";
echo $char->desc." </i>)<br />";
}
}
?>
As I wrote in the comment, fetch the page once instead of once for every name in the database.
Pseudo code for my comment:
users = <get users from database>
webpage = <get webpage contents>
for (user in users)
<check if user exists in webpage>
As mentioned in the comments you're calling a webpage for each entry in your database, assuming that's about 2 seconds per call it's going to slow you down a lot.
Why don't you call the page once and pass the contents of it into the check_online() function as a parameter so your code would look something like this which will speed it up by quite a few magnitudes:
$content=file_get_contents("http://www.tibia.com/community/?subtopic=worlds&worl‌​d=Isara",0);
$q1=mysql_query("SELECT * FROM isara");
while($r1=mysql_fetch_array($q1)){
$named=$r1['name'];
$idd=$r1['id'];
$descd=$r1['desc'];
$online=check_online($named,$content);
$char = new Character($r1['name'],$r1['id'],$r1['desc']);
if($online == "online"){
$char->rank = $i++;
}
else{
$char->rank = 0;
}
$arr[] = $char;
}
?>
<br />
<h2 style="color:green">Online enemies</h2>
<?php
foreach ($arr as $char) {
if($char->rank>=1){
echo "<a style=\"color:green\" href=\"http://www.tibia.com/community/?subtopic=characters&name=$char->name\">";
echo $char->name." ";
echo "</a>";
echo level($char->name)."<b> ";
echo vocation($char->name)."</b> (<i>";
echo $char->desc." </i>)<br />";
}
}
?>
<br />
<h2 style="color:red">Offline enemies</h2>
<?php
foreach ($arr as $char) {
if($char->rank==0){
echo "<a style=\"color:red\" href=\"http://www.tibia.com/community/?subtopic=characters&name=$char->name\">";
echo $char->name." ";
echo "</a>";
echo level($char->name)."<b> ";
echo vocation($char->name)."</b> (<i>";
echo $char->desc." </i>)<br />";
}
}
?>
and your check_online() function would look something like this:
function check_online($name,$content){
$count=substr_count($name, " ");
if($count > 0){ $ex=explode(" ",$name); $namez=$ex[1]; $nameused=$namez; }
else{ $nameused=$name; }
if(preg_match("/$nameused/",$content)){ $status="online"; }
else{ $status="offline"; }
return $status;
}
You can also do the following to make it faster
Stop using select * which is very bad on innodb
Put better indexes on your database to make the recordset return faster
Install PHP 5.4 as it's faster especially as you're creating a new object in each iteration
Use a byte code accelerator/cache such as xdebug
you should avoid using distinct (*) keyword in your SQL Query
for more information read this http://blog.sqlauthority.com/category/sql-coding-standards/page/2/

how to check if foreach loop empty when using json and php

i'm using JSON to get data and then PHP to display. so...
i'm showing everything available to a person and i want to echo a message when the loop is blank/empty that "there's nothing available" because right now it just shows a blank screen when there is no data... any ideas??
<?
foreach($json['available'] as $r) {
echo '<li>' .$r['item'].'</li>';
}}
?>
Just use an if statement and check if $json['available'] is empty with empty().
if( empty( $json['available'])) {
echo '<li>No items are available</li>';
} else {
foreach($json['available'] as $r) {
echo '<li>' .$r['item'].'</li>';
}
}
Use empty to check if $json contains something or not.
Assuming that $json['available'] is going to be an empty array at worst:
if (!$json['available']) {
echo "nothing to show!";
}
else {
// your current code
}
If it's possible that $json['available'] might not even exist, a more "heavy-handed" alternative is
if (empty($json['available'])) {
echo "nothing to show!";
}

How do I close this php statement correctly?

Im attempting to create a simple list out of some elements I stole from a more complex list of rows etc., I just need list out the values in single row separated by commas.
<?php foreach ($document_items as $document_item)
{
if ($document_item->document_id == $document->id)
{
if (nbf_common::nb_strlen($document_item->product_code) > 0)
{
echo nbf_common::nb_strlen($document_item->product_code);
}
;} ?>
;} ?>
<?php } ?>
The Result I get follows "3 ;} ?> 3 ;} ?> 4 ;} ?> 3 ;} ?> "
Thanks in advance
Micah
try this
<?php
foreach ($document_items as $document_item)
{
if ($document_item->document_id == $document->id)
{
if (nbf_common::nb_strlen($document_item->product_code) > 0)
{
echo nbf_common::nb_strlen($document_item->product_code);
}
}
}
?>
Fore more detail PHP Tags
Change the #9, #10, remove #11 line. What you're doing is printing characters: ;} ?>
and are syntactically wrong. This is proper:
<?php foreach ($document_items as $document_item)
{
if ($document_item->document_id == $document->id)
{
if (nbf_common::nb_strlen($document_item->product_code) > 0)
{
echo nbf_common::nb_strlen($document_item->product_code);
}
} // here
} // here
?>
Also for the "comma separated" part, put required values in a variable and echo it at the end.
Could be like this:
<?php
$string = '';
foreach ($document_items as $document_item)
{
if ($document_item->document_id == $document->id)
{
if (nbf_common::nb_strlen($document_item->product_code) > 0)
{
$string .= nbf_common::nb_strlen($document_item->product_code).',';
}
}
}
echo rtrim($string, ','); // remove the last comma
?>
or use a temp array to glue them at the end:
<?php
$lines = array();
foreach ($document_items as $document_item)
{
if ($document_item->document_id == $document->id)
{
if (nbf_common::nb_strlen($document_item->product_code) > 0)
{
$lines[] = nbf_common::nb_strlen($document_item->product_code);
}
}
}
echo implode(',', $lines); // bind them with comma
?>
I'm not sure why you have all those extra ?>. The pattern is:
<?php
// PHP code goes here
?>
i.e. every <?php has a matching ?>; no more, no less.1
1. Other than the case that #Mihai points out in the comment below...
To understand the php tags you might want to think that you are in an HTML file and you are intrerrupting the HTML flow with
When writing PHP only files (classes, interfaces, traits lists of functions and similar grouping of application code with no templating) it is advisable to open at the very first character in the file and not end it at all.
When writing template files however it is advisable to use php's alternate syntax:
<?php if($x): ?>
<?php elseif($y): ?>
<?php else: ?>
<?php endif; ?>
Instead of the standard:
<?php if($x) { ?>
<?php } else if($y) { ?>
<?php } else { ?>
<?php } ?>

Preventing PHP printing Null Array Results?

I cannot get my PHP script to echo the second else statement if the first result empty.
The way my script currently works is "Print Addresses (from another array) > List Comments", however even if a comment is empty for an address is will either print the comments or nothing, I cannot make the script echo the word "No comment".
if(!empty($row['id']))
{
echo "$row[comment]<br/>";
}
else
{
echo "no comment<br/>";
}
Any help appreciated. Thanks.
Assuming this comes from a database and each row has an id, this will always be true:
if(!empty($row['id']))
Try:
if(!empty($row['comment']))
If id is something else, the same logic applies: check the value that you intend to print:
if (!empty($row['id']) && !empty($row['comment']))
{
echo $row['comment'].'<br/>';
}
else
{
echo "no comment<br/>";
}
EDIT: If this code is looping through all comments attached to a post or something, there will never be any output if there are no comments to loop through. In that case try something like this:
if (count($comments) === 0)
{
echo "no comments<br />";
}
else
{
foreach ($comments as $row)
{
if (!empty($row['comment']))
{
echo $row['comment'].'<br />';
}
else
{
echo "no comment<br />";
}
}
}
OR:
$comment_count = 0;
foreach ($comments as $row)
{
if (!empty($row['comment']))
{
echo $row['comment'].'<br />';
$comment_count++; // We have at least one comment
}
else
{
echo "no comment<br />";
}
}
if ($comment_count === 0) echo 'no comments<br />';

Categories