How can I limit the total number of SimpleXML results? - php

I'm looking to limit to the first 5 results returned here.
This works, but it does not limit the data set:
<?php
foreach($sxml->status as $status){
$name = $status->user->name;
$image =$status->user->profile_image_url;
$update =$status->text;
$url = "http://twitter.com/" .$status->user->screen_name;
echo "<li><img src=\"" . $image . "\" alt=\"" . $name . " image\" />" . $name . " " . $update . "</li>";
}
?>
I've tried this:
<?php
for($n = 0; $n <= 5; $n++){
$name = $sxml->$status[$n]->user->name;
$image = $sxml->$status[$n]->user->profile_image_url;
$update = $sxml->$status[$n]->text;
$url = "http://twitter.com/" . $sxml->$status[$n]->user->screen_name;
echo "<li><img src=\"" . $image . "\" alt=\"" . $name . " image\" />" . $name . " " . $update . "</li>";
}
?>
and am really kind of unsure why it doesn't work. If I simply do:
<?php echo $sxml->status[0]->user->name ?>
then I get the proper result. But when attempting it within the for loop, I get NULL.
Perhaps some kind of while? A different setup altogether? Thanks so much for any help you can give on this.

Change this:
for($n = 0; $n <= 5; $n++){
$name = $sxml->$status[$n]->user->name;
$image = $sxml->$status[$n]->user->profile_image_url;
$update = $sxml->$status[$n]->text;
$url = "http://twitter.com/" . $sxml->$status[$n]->user->screen_name;
echo "<li><img src=\"" . $image . "\" alt=\"" . $name . " image\" />" . $name . " " . $update . "</li>";
}
To this:
for($n = 0; $n <= 5; $n++){
$name = $sxml->status[$n]->user->name;
$image = $sxml->status[$n]->user->profile_image_url;
$update = $sxml->status[$n]->text;
$url = "http://twitter.com/" . $sxml->status[$n]->user->screen_name;
echo "<li><img src=\"" . $image . "\" alt=\"" . $name . " image\" />" . $name . " " . $update . "</li>";
}
You accidentally were writing this:
<?php echo $sxml->$status[0]->user->name ?>
Where it was trying to us $status[0] as a variable variable and of course, that doesn't exist and is thus undefined/null.

If you had something that works, why overcomplicate things by changing everything? Just limit the processing to the first N entries.
$i = 0;
foreach ($sxml->status as $status) {
if (++$i > 5) {
// stop after 5 loops
break;
}
// the rest is identical
}

Btw, $n = 0; $n <= 5; $n++ will limit to the first 6 entries, not 5.
$n = 0; $n < 5; $n++ will do what you asked for.

Don't you mean
$n = 0; $n < 4; $n++

I've also tried this, and it works great :-)
foreach ($xml->item as $item) {
if (++$i > 5) { break; }
$item->title . '';
} //foreach()
Note I'm not using $i = 0; it seems to know that by default ;-)
I hope this helps some one.

Related

PHP - Search results not paginating

I'm trying to get search results to paginate if there are greater than 10 items found in the database. For some reason, even though the code recognises there are more than 10 items and creates links for subsequent pages, all search results are listed on the first page only. Anyone able to help please? Code is below:
for($i = 0; $i < $terms_count; $i++)
{
$search_terms_array[$i] = trim($search_terms_array[$i]);
${"query".$i} = $this->mysqli_link->query("SELECT prod_id, prod_tags FROM table WHERE prod_tags LIKE '%" . $search_terms_array[$i] . "%'");
if(${"query".$i}->num_rows < 1)
{
$zerocount++;
}
else
{
$rows = array();
while($row = ${"query".$i}->fetch_array())
{
$rows[] = $row;
}
foreach($rows as $row)
{
$search_id_results[] = $row['prod_id'];
}
}
}
if($zerocount == $terms_count)
{
echo $this->err_handle->fetch_error_text("search_terms_0_results");
return;
}
else
{
$search_results = array_values(array_unique($search_id_results));
$search_results_count = count($search_results);
$search_page_count = ceil($search_results_count / 10);
$search_page_first_result = ($search_page - 1) * 10;
echo '<p>Go to page: ';
for($i = 1; $i <= $search_page_count; $i++)
{
if($i == $search_page)
{
echo " <strong>" . $i . "</strong>";
}
else
{
echo ' ' . $i . '';
}
}
echo '</p><p> </p><p> </p>';
for($i = 0; $i < $search_results_count; $i++)
{
$query = $this->mysqli_link->query("SELECT * FROM table WHERE prod_id='" . $search_results[$i] . "' LIMIT " . $search_page_first_result . ", 10");
while($row = $query->fetch_array())
{
echo "<h4>" . $row['prod_name'] . "</h4><p><img src=\"includes/images/product_images/" . $row['prod_category'] . "/" . $row['prod_pic_filename'] . "\" alt=\"\" width=\"150\" height=\"200\" /></p><p>Price: £" . $row['prod_price'] . "</p><p>" . $row['prod_code'] . "</p><input type=\"number\" name=\"prod_qty\" maxlength=\"2\" /><input type=\"submit\" name=\"add_to_basket\" value=\"Add To Basket\" /></form></p><p> </p><p> </p>";
}
}
echo '<p>Go to page: ';
for($i = 1; $i <= $search_page_count; $i++)
{
if($i == $search_page)
{
echo " <strong>" . $i . "</strong>";
}
else
{
echo ' ' . $i . '';
}
}
echo '</p><p> </p><p> </p>';
}
Ok so I found a solution to this problem and the full function is now as follows:
public function product_search($search_terms, $search_page, $search_flag_check)
{
if($search_flag_check == "invalid")
{
echo $this->err_handle->fetch_error_text("invalid_ns_term");
return;
}
if($search_terms == "")
{
echo $this->err_handle->fetch_error_text("no_search_string");
return;
}
$search_terms = htmlspecialchars($search_terms);
$search_terms = $this->mysqli_link->real_escape_string(filter_var($search_terms, FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_FLAG_NO_ENCODE_QUOTES));
$search_terms_array = explode(" ", $search_terms);
$terms_count = count($search_terms_array);
$zerocount = 0;
$search_id_results = array();
for($i = 0; $i < $terms_count; $i++)
{
$search_terms_array[$i] = trim($search_terms_array[$i]);
${"query".$i} = $this->mysqli_link->query("SELECT prod_id, prod_tags FROM table WHERE prod_tags LIKE '%" . $search_terms_array[$i] . "%'");
if(${"query".$i}->num_rows < 1)
{
$zerocount++;
}
else
{
$rows = array();
while($row = ${"query".$i}->fetch_array())
{
$rows[] = $row;
}
foreach($rows as $row)
{
$search_id_results[] = $row['prod_id'];
}
}
}
if($zerocount == $terms_count)
{
echo $this->err_handle->fetch_error_text("search_terms_0_results");
return;
}
else
{
$search_results = array_values(array_unique($search_id_results));
$search_results_count = count($search_results);
$search_page_count = ceil($search_results_count / 10);
$search_page_first_result = ($search_page - 1) * 10;
$search_page_results_limit = 10;
if($search_page_first_result < 1)
{
$search_page_first_result = 1;
}
echo '<p>Go to page: ';
for($i = 1; $i <= $search_page_count; $i++)
{
if($i == $search_page)
{
echo " <strong>" . $i . "</strong>";
}
else
{
echo ' ' . $i . '';
}
}
echo '</p><p> </p><p> </p>';
$search_page_upper_limit = $search_page_first_result + 9;
if(array_key_exists($search_page_upper_limit, $search_results))
{
$search_results_limit = $search_page_first_result + $search_page_results_limit;
}
else
{
end($search_results);
$search_results_limit = key($search_results);
reset($search_results);
}
for($i = $search_page_first_result; $i <= $search_results_limit; $i++)
{
$query2 = $this->mysqli_link->query("SELECT * FROM table WHERE prod_id='" . $search_results[$i] . "'");
$row = $query2->fetch_array();
echo "<h4>" . $row['prod_name'] . "</h4><p><img src=\"includes/images/product_images/" . $row['prod_category'] . "/" . $row['prod_pic_filename'] . "\" alt=\"\" width=\"150\" height=\"200\" /></p><p>Price: £" . $row['prod_price'] . "</p><p>" . $row['prod_code'] . "</p><input type=\"number\" name=\"prod_qty\" maxlength=\"2\" /><input type=\"submit\" name=\"add_to_basket\" value=\"Add To Basket\" /></form></p><p> </p><p> </p>";
}
echo '<p>Go to page: ';
for($i = 1; $i <= $search_page_count; $i++)
{
if($i == $search_page)
{
echo " <strong>" . $i . "</strong>";
}
else
{
echo ' ' . $i . '';
}
}
echo '</p><p> </p><p> </p>';
}
}
It took a bit of thinking and I was about to give up, but then I thought about using the array keys to calculate the limits for each search page and after a bit of googling on relevant PHP array functions it all fell into place quite well.
I understand the code may not be very tidy right now and there may be ways to optimize/improve it, however for the time being it does the job.

PHP Comparing 0 does not work

I'm trying to set a checkbox as checked in php based on an hour fields from a comma separated value string. It works well for 1-23 but for some reason hour 0 always displays as checked:
<?php
myhours = explode(",", substr($arruser['arhours'],0,strlen($arruser['arhours']) - 1));
$checked = "";
for($hour = 0; $hour <= 23; $hour++) {
if(count($myhours) > 0) {
for($h = 0; $h <= count($myhours); $h++) {
if((int)$hour == (int)$myhours[$h]) {
$checked = " checked ";
break;
}
}
} else {
$checked = "";
}
if(strlen($hour) == 1) {
echo "<td><input type=checkbox " . $checked . " value=" . $hour . " onchange=\"updatehour(" . $_REQUEST['user'] . ",this.checked, '" . $hour . "')\">0$hour:00</td>";
} else {
echo "<td><input type=checkbox " . $checked . " value=" . $hour . " onchange=\"updatehour(" . $_REQUEST['user'] . ",this.checked, '" . $hour . "')\">$hour:00</td>";
}
$checked = "";
}
?>
The problem is straightforward; look at the outer loop:
for ($hour = 0; $hour <= 23; $hour++) {
Consider only the first iteration, so $hour is int(0). Further in the code:
if(count($myhours) > 0) {
for($h = 0; $h <= count($myhours); $h++) {
Pay close attention to the loop condition:
$h <= count($myhours)
Consider the last iteration of that loop, so $h equals the size of your array.
if ((int)$hour == (int)$myhours[$h]) {
At this point $myhours[$h] is undefined because the array index is out of bounds (and a notice would have been emitted) and so (int)$myhours[$h] becomes (int)null which is int(0). The comparison is therefore always true when $hour has the value of int(0).
The solution is to change the loop condition to:
$h < count($myhours)
Not exactly and answer, but your code could be reduced to this:
$myhours = array(0, 10, 13, 20);
for($hour = 0; $hour <= 23; $hour++) {
echo '<td><input type="checkbox"' . ( in_array($hour, $myhours) ? ' checked' : '' ) . ' value="' . $hour . '" onchange="updatehour(' . $_REQUEST['user'] . ', this.checked, ' . $hour . ')">' . str_pad($hour, 2, '0', STR_PAD_LEFT) . ':00</td>';
}
No need for a second loop and more variables here. Also be aware to not output values from $_REQUEST directly without any check.
Demo
Try before buy
Problem solved. It was actually the count($myhours) that was causing the problem. Basically even with an empty string it still returns an array with 1 element. Changed to check if count($myhours) > 1 and everything is working as expected:
<?php
$myhours = explode(",", substr($arruser['arhours'],0,strlen($arruser['arhours']) - 1));
$checked = "";
for($hour = 0; $hour <= 23; $hour++) {
if(count($myhours) > 1) {
for($h = 0; $h <= count($myhours); $h++) {
if((int)$hour == (int)$myhours[$h]) {
$checked = " checked ";
break;
}
}
} else {
$checked = "";
}
if(strlen($hour) == 1) {
echo "<td><input type=checkbox " . $checked . " value=" . $hour . " onchange=\"updatehour(" . $_REQUEST['user'] . ",this.checked, '" . $hour . "')\">0$hour:00</td>";
} else {
echo "<td><input type=checkbox " . $checked . " value=" . $hour . " onchange=\"updatehour(" . $_REQUEST['user'] . ",this.checked, '" . $hour . "')\">$hour:00</td>";
}
$checked = "";
}
?>

Return multiple paragraph tags from php function

Hello I've got the following function:
function getProductInformation($productArr, $productNumber){
for ($i=0; $i < count($productArr[0]); $i++) {
$products[] = $productArr[0][$i];
}
for ($i=0; $i < count($productArr[1]); $i++) {
$sizes[] = $productArr[1][$i];
}
for ($i=0; $i < count($productArr[2]); $i++) {
$prices[] = $productArr[2][$i];
}
?><p><?php
return $products[$productNumber] . " " . $sizes[$productNumber] . " " . $prices[$productNumber];
?></p><?php
}
If i echo the function with an array and a number as params it will return the following:
<p>product size price</p>
Instead of the function only returning one paragraph i would like the result to look like this
<p>product</p> <p>size</p> <p>price</p>
All help appreciated!
Include HTML tags in strings:
function getProductInformation($productArr, $productNumber){
$products = array_values($productArr[0]);
$sizes = array_values($productArr[1]);
$prices = array_values($productArr[2]);
return "<p>" . $products[$productNumber] . "</p> <p>" . $sizes[$productNumber] . "</p> <p>" . $prices[$productNumber] . "</p>";
}

PHP: Undefined offset in for loop

While making a photo gallery I encountered a problem. With every photo I try to show how many comments it has, however if a photo has 0 comments it will give me an 'undefined offset' error. I have no idea what I am doing wrong because it does show that there are 0 comments.
This is the code of what is relevant to the problem:
(The problem occurres in the line: if($reacties[$i]==0){)
if((isset($_GET['vanafFoto'])) AND (intval($_GET['vanafFoto']>=0)) AND (intval($_GET['vanafFoto'] < $countFotos))){
$begin = intval($_GET['vanafFoto']);
if(($begin + $aantalFotos) <= $countFotos){
$eind = ($begin + $aantalFotos);
} // end if
else {
$eind = $countFotos;
} // end else
} // end if
else {
$begin = 0;
$eind = $aantalFotos;
} // end else
$countFotos = count($fotoArray);
// path naar echte foto
} // end else
echo "<table border='0' cellpadding='0' cellspacing='2'><tr><td ><b>" . $pathspatie . "</b> <small>(" . $count . ")</small>
<br><br><center><small>Pictures " . ($begin + 1) . " - " . $eind . "</small></center></td></tr></table>";
if(($begin - $aantalFotos) >= 0){
$navigation = "<a href='" . $_SERVER['PHP_SELF'] . "?page=album&boek=" . $originalPath . "&vanafFoto=" . ($begin - $aantalFotos) . "'><</a> " . $navigation;
} // end if
if(($begin + $aantalFotos) < $count){
$navigation .= " <a href='" . $_SERVER['PHP_SELF'] . "?page=album&boek=" . $originalPath . "&vanafFoto=" . ($begin + $aantalFotos) . "'>></a>";
} // end if
echo $navigation . "<br><br>";
echo "</td></tr><tr>";
$fotonr = 1;
for($i=$begin; $i < $eind; $i++){
$thumb = str_replace($path2, $thumbPath, $fotoArray[$i]);
echo "<td align='center'><a href='" . $_SERVER['PHP_SELF'] . "?page=album&boek=" . $originalPath . "&fotoID=" . $i . "'><img border='0' src='" . $thumb . "' height='100'><br>";
echo "<small>reacties (";
if($reacties[$i]==0){ // error occurres here.
echo "0";
} // end if
else {
echo $reacties[$i];
} // end else
echo ")</small>";
echo "</a></td>";
$fotonr++;
if($fotonr == ($clm + 1)){
echo "</tr>\n<tr>";
$fotonr = 1;
} // end if
} // end for
If anyone can see what the problem is it would be great!
I did not understand you exact goal but maybe it is better to write one more check:
if(!isset($reacties[$i]) || $reacties[$i]==0){
echo "0";
}

PHP Array Declaration

for ($k = 0; $k < $count; $k++) {
$master[$k] = $namearray[$k], $streetarray[$k], $localityarray[$k], $regionarray[$k], $postalcodearray[$k], $phonearray[$k];
}
I'd like to declare a new array and set values from other arrays already declared. I thought I could just loop through the keys and set the values but this doesn't work for me.
Full code below. I'm parsing yellow pages search results and trying to output search results into a csv file. In the code below I removed the loop and only added a few values to the array to make sure my bug wasn't something else.
<?php
// include required functions
include('simple_html_dom.php');
$url = "http://www.yellowpages.com/" . $_POST['city'] . '-' . $_POST['state'] . '-' . $_POST['postalcode'] . '/' . $_POST['category'] . '?g=' . $_POST['city'] . '%2C+' . $_POST['state'] . '+' . $_POST['postalcode'] . '&q=' . $_POST['category'];
// get DOM from URL
$html = file_get_html($url);
// find all business name
foreach($html->find('h3.business-name') as $name)
//echo $name->innertext . '<br />';
$namearray[] = $name->innertext;
// find all business street address
foreach($html->find('span.street-address') as $street)
//echo $street->innertext . '<br />';
$streetarray[] = $street->innertext;
// find all business city
foreach($html->find('span.locality') as $locality)
//echo $locality->innertext . '<br />';
$localityarray[] = $locality->innertext;
// find all business state
foreach($html->find('span.region') as $region)
//echo $region->innertext . '<br />';
$regionarray[] = $region->innertext;
// find all business postal code
foreach($html->find('span.postal-code') as $postalcode)
//echo $postalcode->innertext . '<br />';
$postalcodearray[] = $postalcode->innertext;
// find all business phone
foreach($html->find('span.business-phone') as $phone)
//echo $phone->innertext . '<br />';
$phonearray[] = $phone->innertext;
?>
<p>Search results for: <?php echo $_POST['category'] . ' ' . $_POST['city'] . ' ' . $_POST['state'] . ' ' . $_POST['postalcode']; ?></p>
<?php
// Output results
$count = count($namearray);
for ($i = 0; $i < $count; $i++) {
echo $namearray[$i] . '<br />';
echo $streetarray[$i] . '<br />';
echo $localityarray[$i] . ',' . $regionarray[$i] . ' ' . $postalcodearray[$i] . '<br />';
echo $phonearray[$i] . '<br />' . '<br />';
}
$list = array (
array($namearray[0], $streetarray[0], $localityarray[0], $regionarray[0], $postalcodearray[0], $phonearray[0]),
array($namearray[1], $streetarray[1], $localityarray[1], $regionarray[1], $postalcodearray[1], $phonearray[1]),
array($namearray[2], $streetarray[2], $localityarray[2], $regionarray[2], $postalcodearray[2], $phonearray[2]),
array($namearray[3], $streetarray[3], $localityarray[3], $regionarray[3], $postalcodearray[3], $phonearray[3])
);
$fp = fopen('hrpsearch.csv', 'w');
foreach ($list as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
?>
Try:
$master = array();
for ($k = 0; $k < $count; $k++) {
$master[$k] = array
( $namearray[$k]
, $streetarray[$k]
, $localityarray[$k]
, $regionarray[$k]
, $postalcodearray[$k]
, $phonearray[$k]
);
}
This will create a new two-dimensional array for you with associated keys for every child array.
Try
for($k = 0; $k < $count; $k++) {
$master[$k] = array(
$namearray[$k],
$streetarray[$k],
$localityarray[$k],
$regionarray[$k],
$postalcodearray[$k],
$phonearray[$k]
);
}
Maybe do you just want to achieve this?
$master[$k] = array($namearray[$k], $streetarray[$k], $localityarray[$k], $regionarray[$k], $postalcodearray[$k], $phonearray[$k]);
I would suggest using instead:
$master[$k]['name'] = $namearray[$k];
$master[$k]['street'] = $streetarray[$k];
...
The retrieval of the data will be more readable.
I think #DaveRandom's answer is what (I imply) you are looking for.
Since a PHP array can be of any type (scalar, array, object, etc.), you need to tell it you are assigning an array with the construct array().
The end result would be:
$master[$k] = array($namearray[$k], $streetarray[$k], $localityarray[$k], $regionarray[$k], $postalcodearray[$k], $phonearray[$k]);
Try this
for ($k = 0; $k < $count; $k++) {
$master[$k] = array($namearray[$k], $streetarray[$k], $localityarray[$k], $regionarray[$k], $postalcodearray[$k], $phonearray[$k]);
}
or is better to create associative array
for ($k = 0; $k < $count; $k++) {
$master[$k] = array('name'=>$namearray[$k],
'street'=>$streetarray[$k],
'city'=>$localityarray[$k],
'region'=>$regionarray[$k],
'postalCode'=>$postalcodearray[$k],
'phone'=>$phonearray[$k]);
}
You also need to check if your array elements are not empty or just put # befor array element like 'name'=>#$namearray[$k]. It will remove any warning if element doesn't exist.

Categories