PHP paging database information - php

I am displaying search results from a database in my website. I am able to have the links to the number of pages show and have the first few results on the first page. But when I go to page 2 there is no results same with the 3rd and 4 pages that display.
php code
//This checks to see if there is a page number. If not, it will set it to page 1
if (isset($_GET["page"])) { $page = $_GET["page"]; } else { $page=1; };
$start_from = ($page-1) * 5;
///////////set search variables
$property = $_POST['property'];
$bedroom = $_POST['BedroomNumber'];
$bathroom = $_POST['BathroomNumber'];
$priceMin = $_POST['PriceMin'];
$priceMax = $_POST['PriceMax'];
$sizeMin = $_POST['SizeMin'];
$sizeMax = $_POST['SizeMax'];
$termlease = $_POST['TermLease'];
//////////search
if(isset($_POST['utilities']) && is_array($_POST['utilities'])) {
foreach($_POST['utilities'] as $check) {
//echoes the value set in the HTML form for each checked checkbox.
//so, if I were to check 1, 3, and 5 it would echo value 1, value 3, value 5.
//in your case, it would echo whatever $row['Report ID'] is equivalent to.
}
}
$sql = $mysqli->query("select * from propertyinfo where Property like '%$property%' and NumBed >= '%$bedroom%' and NumBath >= '%$bathroom%' and Footage >='$sizeMin' and Footage <='$sizeMax' and Price >= '$priceMin' and Price <= '$priceMax' and utilities like '%$check%' and TermLease like '%$termlease%' ORDER BY Price ASC LIMIT $start_from, 5");
if($sql->num_rows){
while ($row = $sql->fetch_array(MYSQLI_ASSOC)){
echo '<div id="listing">
<div id="propertyImage">
<img src="uploadimages/'.$row['imageName1'].'" width="200" height="150" alt=""/>
</div>
<div id="basicInfo">
<h2>$'.$row['Price'].' | '.$row['Footage'].' sqft.</h2>
<p style="font-size: 18px;"># '.$row['StreetAddress'].', '.$row['City'].', BC</p>
<p>'.$row['NumBed'].' Bedrooms | '.$row['NumBath'].' Bathrooms | '.$row['Property'].'</p>
<br>
<p>View Full Details
</div>
</div>';
}
}
else
{
echo '<h2>0 Search Results</h2>';
}
$sqlPage = $mysqli->query("select count(id) from propertyinfo where Property like '%$property%' and NumBed >= '%$bedroom%' and NumBath >= '%$bathroom%' and Footage >='$sizeMin' and Footage <='$sizeMax' and Price >= '$priceMin' and Price <= '$priceMax' and utilities like '%$check%' and TermLease like '%$termlease%'");
$row2 = $sqlPage->fetch_array();
$total_records = $row2[0];
$total_pages = $total_records > 0 ? ceil($total_records / 5) : 0;
for ($i=1; $i<=$total_pages; $i++) {
echo "<a href='search.php?page=".$i."'>".$i."</a> ";
};

Contrary to your overview's select you've got no filter on the select used for the page-count. As such the latter will be (potentially) higher, thus indicating a page that isn't there. You should change the $sqlPage line to the following to get a matching amount of pages.
$sqlPage = $mysqli->query("select count(id) from propertyinfo where Property like '%$property%' and NumBed >= '%$bedroom%' and NumBath >= '%$bathroom%' and Footage >='$sizeMin' and Footage <='$sizeMax' and Price >= '$priceMin' and Price <= '$priceMax' and utilities like '%$check%' and TermLease like '%$termlease%'");
Also you should change the $total_pages line to the following, as you might otherwise get a division by 0 error:
$total_pages = $total_records > 0 ? ceil($total_records / 5) : 0;
EDIT irt comments below
If you go to the next page data doesn't get reposted and thus al you parameters are empty. There are a couple of ways to ensure the data is available on the next pages. You could output a form and repost it, you could append the data to the GET query, or you can store it in a session, a file or a database. Anyway, a quick solution in your case would be adding the following code just before the set search parameters part, which saves POST daat to a session and then uses that data untill new data is posted:
if(!isset($_SESSION)) {
if(!#session_start()) die('Could not start session');
}
if(empty($_POST)) {
if(isset($_SESSION['searchpost'])) $_POST = $_SESSION['searchpost'];
} else {
$_SESSION['searchpost'] = $_POST;
}

Related

Php pagination from Mysql Select * Where; If click on next page number, then displays all rows from Mysql

In input field user enters condition - what data to get from mysql. For example, user wants to get mysql rows where month is October (or 10).
Here I get user input $date_month = $_POST['date_month'];
Then mysql statement and code for pagination
try {
$sql = $db->prepare("SELECT * FROM 2_1_journal WHERE RecordMonth = ? ");
$sql->execute(array($date_month));
foreach ($sql as $i => $row) {
}
$number_of_fetched_rows = $i;
$number_of_results_per_page = 100;
$total_pages = ceil($number_of_fetched_rows / $number_of_results_per_page);
if (isset($_GET['page']) && is_numeric($_GET['page'])) {
$show_page = $_GET['page'];
if ($show_page > 0 && $show_page <= $total_pages) {
$start = ($show_page -1) * $number_of_results_per_page;
$end = $start + $number_of_results_per_page;
}
else {
$start = 0;
$end = $number_of_results_per_page;
}
}
else {
$start = 0;
$end = $number_of_results_per_page;
}
for ($page_i = 1; $page_i <= $total_pages; $page_i++) {
echo "<a href='__filter_mysql_data.php?page=$page_i'>| $page_i |</a> ";
}
}
So, user enters month (10), script displays all rows where month is 10; displays page No 1. But if user click on other page number, script displays all data from mysql (all months, not only 10)
What I see - when click on other page number, page reloads, that means that values of php variables "dissapears". As understand after page reload $date_month value is not set (has lost/"dissapears") ? How to keep the value? Or may be some better solution for pagination?
Update.
Behavior is following:
1) in input field set month 10 (October);
2) click on button and get displayed data from mysql where month is 10 (October); so far is ok
3) click on page number 2 and get displayed all data from mysql (all months, not only 10 (October))
Tried to use LIMIT however it does not help.
Possibly problem is related with this code
for ($page_i = 1; $page_i <= $total_pages; $page_i++) {
echo "<a href='__filter_mysql_data.php?page=$page_i'>| $page_i |</a> ";
}
When click on $page_i for not understandable (for me) reasons get displayed all (not filtered) data from mysql. If I use LIMIT also get displayed not filtered results from mysql....
Use LIMIT in your query, have a look at the following example , you can try something like :
SELECT
*
FROM
2_1_journal
WHERE
RecordMonth = ?
LIMIT [start_row],[number_of_rows_per_page]
So for example lets say you have 2 pages with 10 rows per page then the LIMIT for the 2 queries (one per page) will be:
1) LIMIT 0,10
2) LIMIT 10,10
You should change your query like this:
SELECT * FROM 2_1_journal WHERE RecordMonth = ? LIMIT = $number_of_results_per_page OFFSET ($page_number*$number_of_results_per_page);
Here you need to calculate the page number also and you should use the limit and offset concept of mysql.

echo a certain number of results per page in php

I have a query and loop that displays products depending on an id. Sub-Category id in this case. The code is as follows:
<div id="categoryproducts">
<?php
$productsGet = mssql_query("SELECT * FROM Products WHERE SubCatID = ".$_GET['scid']."");
while ($echoProds = mssql_fetch_array($productsGet)) {
?>
<div class="productbox">
<div class="productboximg">
<img src="<?php echo $echoProds['ProdThumb']; ?>" height="58" width="70" alt="" />
</div>
<div class="productboxdtl">
<h3><?php echo $echoProds['Title']; ?></h3>
<p><?php echo $echoProds['Synopsis']; ?></p>
</div>
<div class="productboxprc">
Price <strong>£<?php echo $echoProds['Price']; ?></strong>
</div>
<div class="productboxmore">
</div>
</div>
<?php
}
?>
<div id="shoplistpagesbot" class="shoplistpages">
Results Pages: 1 2 [Next »]
</div>
I am unsure how to display a certain number of products per page, as shown there is a mechanism for changing between pages, I need to somehow code that after a certain number of products, say 5 for example, the remainder are displayed on the next page.
Can anyone suggest how to do this? Or point me in the correct dirrection as to which functions I should be looking into.
Sorry if it isn't very clear, I am new to PHP. The DB im using is a MS SQL one not MySQL
Depends what version of MSSQL you are using.
I'm not a user of MSSQL, but apparently the SQL Server 2000 uses the TOP command, whilst SQL Server 2005 uses the BETWEEN command. A Google search should provide you with several tutorials on each but I am going to assume that you are using the 2005 version.
To return the items on page number $page_number, the general algorithm is :
// The most common way to specify which page to display is a GET variable. There
// are others ways and if you'd prefer them, just set $page_number to get the
// number from there instead. Don't forget to filter all data from the GET array
// as a user may try to insert harmful data, such as XSS attacks.
$page_number = $_GET['page'];
$scid = $_GET['scid'];
// Calculate the range of items to display.
$min = $page_number * $items_per_page;
$max = $min + $items_per_page;
$sql = "SELECT * FROM Products WHERE SubCatID = \"{$scid}\" BETWEEN {$min} AND {$max}";
To get the remaining number of items, you'll need a separate database query returning the total number of items.
$sql = "SELECT COUNT(*) FROM Products WHERE SubCatID = \"{$scid}\"";
// Using the same $max as before as it is the number of items on the page plus
// total items on previous pages, but we'll redefine it here just in case.
$max = ($page_number * $items_per_page) + $items_per_page;
// Assume that $total_rows is the number returned from executing the count query.
$remaining_items = $total_rows - $max;
Now to generate links to all the other pages.
$current_page = $_GET['page'];
$total_pages = $total_rows / $items_per_page;
if($current_page != 1) {
$previous = $current_page - 1;
echo "Previous";
}
for($i = 1; $i <= $total_pages; $i++) {
echo "{$i}";
}
if($current_page != $total_pages) {
$next = $current_page + 1;
echo "Next";
}
$pagenumber = $_GET['pagenumber'];
$recordsperpage = 30;
$first = ($pagenumber*$recordperpage)-$recordperpage;
$last = $pagenumber*$recordsperpage;
$productsGet = mysql_query("SELECT * FROM Products WHERE SubCatID = '".$_GET['scid']."' LIMIT $first,$last");
Have this at the top of the page and pass a GET parameter in your links e.g. browse.php?pagenumber=1;
You can calculate the number of pages by dividing total rows in the recordset by your $recordsperpage variable.
Then just use a simple for loop to output the navigation links e.g.:
for($i = 1; $i <= $totalpages; $i++) {
echo "<a href='browse.php?pagenumber=$i'>$i</a>";
}
Where $totalpages is the result of dividing total rows in the recordset by your $recordsperpage variable.
Hope this helps
Here it is for MS SQL:
SELECT TOP 10 *
FROM (SELECT TOP 20 * FROM products ORDER BY ID) as T
ORDER BY ID DESC
Basically are selecting the top 10 records from the top 20 in reverse order here. Hence you get the second 10 in the recordset.
Replace the 10 with the number of records per page and the 20 with the $last variable above.
Hope this clears it up

How to split search results into pages?

How to split the search results into pages? (like page 1, page 2, page 3...)
When the user searches for products on my e-commerce website, I want results to be split into several pages showing around 20 products per page. The search results are the outcome of database query.
For example: If the user searches for Samsung mobiles so my query will be:
SELECT * FROM PRODUCTS WHERE BRAND='SAMSUNG';
Suppose the above query returns 55 results, how to show them into pages (1,2 and 3)?
I am using PHP, MySQL, Apache on Windows machine.
The appropriate SQL would be adding:
LIMIT start, amount
You can navigate like
search.php?start=20
and then code like:
LIMIT $start, $amount
with
$start = intval($_GET['start']);
and
$amount = 20;
That will result in max 20 records a page.
Use SQL's LIMIT keyword to limit the amount of results from your query; for example:
SELECT * FROM PRODUCTS WHERE BRAND='SAMSUNG' LIMIT 20, 40;
This would select 20 elements, starting at the 40th
Here is the complete code:
<?php
// Requested page
$requested_page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Get the product count
$r = mysql_query("SELECT COUNT(*) FROM PRODUCTS WHERE BRAND='SAMSUNG'");
$d = mysql_fetch_row($r);
$product_count = $d[0];
$products_per_page = 20;
// 55 products => $page_count = 3
$page_count = ceil($product_count / $products_per_page);
// You can check if $requested_page is > to $page_count OR < 1,
// and redirect to the page one.
$first_product_shown = ($requested_page - 1) * $products_per_page;
// Ok, we write the page links
echo '<p>';
for($i=1; $i<=$page_count; $i++) {
if($i == $requested_page) {
echo $i;
} else {
echo ''.$i.' ';
}
}
echo '</p>';
// Then we retrieve the data for this requested page
$r = mysql_query("SELECT * FROM PRODUCTS WHERE BRAND='SAMSUNG' LIMIT $first_product_shown, $products_per_page");
while($d = mysql_fetch_assoc($r)) {
var_dump($d);
}
?>
Hope its help.
Yes you can run a query to get total record count and than use query using limit
exampe:
select count(id) from table_name
This will return total record count in database
In my php learning books, it provides a solution using a PHP class
it looks like this
<!-- language: php -->
<?php
error_reporting(0); // disable the annoying error report
class page_class
{
// Properties
var $current_page;
var $amount_of_data;
var $page_total;
var $row_per_page;
// Constructor
function page_class($rows_per_page)
{
$this->row_per_page = $rows_per_page;
$this->current_page = $_GET['page'];
if (empty($this->current_page))
$this->current_page = 1;
}
function specify_row_counts($amount)
{
$this->amount_of_data = $amount;
$this->page_total=
ceil($amount / $this->row_per_page);
}
function get_starting_record()
{
$starting_record = ($this->current_page - 1) *
$this->row_per_page;
return $starting_record;
}
function show_pages_link()
{
if ($this->page_total > 1)
{
print("<center><div class=\"notice\"><span class=\"note\">Halaman: ");
for ($hal = 1; $hal <= $this->page_total; $hal++)
{
if ($hal == $this->current_page)
echo "$hal | ";
else
{
$script_name = $_SERVER['PHP_SELF'];
echo "$hal |\n";
}
}
}
}
}
?>
then we call it on the script that require paging
<!-- language: php -->
<?php $per_page = 5;
$page = new Page_class($per_page);
error_reporting(0); // disable the annoying error report
$sql="SELECT * FROM table WHERE condition GROUP BY group";
$result=mysql_query($sql) or die('error'.mysql_error());
// paging start
$row_counts = mysql_num_rows($result);
$page->specify_row_counts($row_counts);
$starting_record = $page->get_starting_record();
$sql="SELECT * FROM table WHERE condition GROUP BY group LIMIT $starting_record, $per_page";
$result=mysql_query($sql) or die('error'.mysql_error());
$number = $starting_record; //numbering
$num_rows = mysql_num_rows($result);
if ($num_rows == 0 )
{ // if no result is found
echo "<div class=\"notice\">
<center><span class=note>NO DATA</span></center>
</div>";
}
else {
// while goes here ...
}
?>
// call the page link
<?php
$page->show_pages_link();
?>
hope it helps, just tried it hours ago to my search script page (learning from books)

How to limit items from while loop

This is my while loop from my project :
<?php
$select = "SELECT * FROM nk_showcase";
$query = $db->rq($select);
while ($user = $db->fetch($query)) {
?>
<div class="index">
<img width="200" height="171" alt="<?php echo $user['title']; ?>" src="<?php echo $url; ?>/images/niagakit/<?php echo $user['thumb']; ?>"/>
<h3><?php echo $user['title']; ?></h3>
<p><?php echo $user['url']; ?></p>
</div>
<?php } ?>
As you already know, this while loop will loop for all items they found in my database, so my quuestion is, how to limit this loop only for 10 items only from my database and how to rotate that items every refresh?
In SQL:
$select = "SELECT * FROM nk_showcase LIMIT 0,10";
or in PHP:
$counter = 0;
$max = 10;
while (($user = $db->fetch($query)) and ($counter < $max))
{
... // HTML code here....
$counter++;
}
As to the rotating, see #Fayden's answer.
Rotate as in random, or as the next 10 elements ?
Most RDBMS allow you to order rows by random :
-- MySQL
SELECT * FROM nk_showcase ORDER BY RAND() LIMIT 10
-- PostgreSQL
SELECT * FROM nk_showcase ORDER BY RANDOM() LIMIT 10
Which would select 10 random rows every time you refresh the page
If you want to show the next 10 elements, you would have to paginate the page (and use the LIMIT X OFFSET Y syntax)
You have to change your query $select, try using LIMIT to 10 if you just need the 10 first items or try also with OFFSET if you need to paginate the results.
$select.=" OFFSET $start LIMIT $range;";
Then you need to control the $start and $range variables like:
$size_page=10;
if (!$page) {
$start = 0;
$page=1;
}
else {
$start = ($page - 1) * $size_page;
}
You can notice that $range should be the same value of $size_page and just you need to calculate the $start value for each iteration taking into account the #pages

Pagenav. By clicking next get next lets say "20" records (php/mysql)

I've already created a query to mysql that will give 20 results from mysql table etc. "cat"
heres the calling:
if(isset($_GET['cat']))
{
$query = "SELECT game_title,game_desc,....
FROM games WHERE cat_id='".validate_input($_GET['cat'])."' LIMIT 20";
}
...
by this I manage to get the results I wanted. What I am asking here is how can I create a "button" that will load the next "20" records from table "cat" (something like Buttons).
<?
$cn=mysql_connect("localhost","root","root") or die(mysql_error());
mysql_select_db("db56") or die(mysql_error());
$sql="select count(*) from emp";
$result=mysql_query($sql);
$r=mysql_fetch_row($result);
$record=$r[0];
$pagesize=20;
$totalpages=$record/$pagesize;
$currpage=$_GET["pg"];
if(!isset($currpage))
$start=0;
else {
$currpage--;
$start= $currpage * $pagesize;
}
$end=$start+$pagesize;
$sql="select * from emp limit $start,$pagesize";
$result=mysql_query($sql);
if($result){
print "<table border='1'>";
print "<tr><th>No</th><th>Name</th><th>Date</th></tr>";
while($r=mysql_fetch_row($result))
{
print "<tr><td>$r[0]</td><td>$r[1]</td><td>$r[2]</td></tr>";
}
print "</table>";
}
for($i=1;$i<=$totalpages;$i++){
print "<a href='listemp.php?pg=$i'> $i </a>";
}
?>
If you keep track of what page you're on, in the URL or a hidden field or session variable, you can use that to work out the limit. For example, page 2 should show limit 20 from row 20 (20 times the page offset).
You can pass two SQL parameters to LIMIT (put a comma between them) If you do, the first tells SQL how many records to skip (ie the offset of the first record) and the 2nd parameter is the one you're already using (how many records to return).
So just put a variable in your "next" link that says what page to display. You can pass the offset in this link, but it's pretty common to pass the "page number" instead, and multiply by the number of records per page before sticking it in the sql.
next page
With a bit more work, you can make a "previous page" link, and make the correct links non-clickable when you're at the first/last page.
Pass along a parameter that tells the script that you want another chunk of the results and not just the first batch.
So for the link it could be like this:
example.com/results.php?cat=1&page=2
Where page= will tell the script what page you want to return.
Then you want to turn that LIMIT number you have so that you can work out some simple maths
$results_cnt = 20; //--rows you want per page of results
Now in your script you'll check to see if the page variable has been set. If not, default the start row to return from the first. But as you want to return different pages/sets of results, a little math is needed in order to start at the proper row.
if(isset($_GET["page"]) //--see if the variable is even there
{
$page_num = (int)$_GET["page"]; //--forcing it to always be an integer
$start_row = $results_cnt * ($page_num - 1);
/* --
what happens:
($results_cnt currently at 20)
on page one (page=1), start at row 0
math: 20 * (1 - 1) = 0
on page two (page=2), start at row 20
math: 20 * (2 - 1) = 20
on page three (page=3), start at row 40
math: 20 * (3 - 1) = 40
etc.
*/
}
else
$start_row = 0;
Now, having set the correct starting row, adjust the SQL query to use the variables like so:
if(isset($_GET['cat']))
{
$query = "SELECT game_title,game_desc,....
FROM games
WHERE cat_id='".validate_input($_GET['cat'])."'
LIMIT $start_row, $results_cnt";
}
OK I got it fixed I guess...
in index.php:
<?php
$games = array();
$count = 1;
$total = 0;
if(isset($_GET['cat']))
{
$query = "SELECT game_title,game_desc,.... FROM games WHERE cat_id='".validate_input($_GET['cat'])."' LIMIT 20";
$total = mysql_num_rows(mysql_query("SELECT 1 FROM games WHERE cat_id='".validate_input($_GET['cat'])."'"));
}
$query_result = #mysql_query ($query) OR error(mysql_error(), __LINE__, __FILE__, 0, '', '');
while ($info = #mysql_fetch_array($query_result))
{
/* -- here goes the infos.. */
$games[$info['game_title']]['game_title'] = $info['game_title'];
etc..
if(isset($_GET['cat']))
{
/* -- for template engine */
$page->SetLoop ('PAGES', pagenav($total,$_GET['page'],20,$config['site_url'].'?cat='.$_GET['cat'],1,$lang));
}
--end php
and in funct.php
--start php
function pagenav($total,$page,$perpage,$url,$posts=0)
{
$page_arr = array();
$arr_count = 0;
if($posts)
{
$symb='&';
}
else
{
$symb='?';
}
$total_pages = ceil($total/$perpage);
$llimit = 1;
$rlimit = $total_pages;
$window = 5;
$html = '';
if ($page<1 || !$page)
{
$page=1;
}
if(($page - floor($window/5)) <= 0)
{
$llimit = 1;
if($window > $total_pages)
{
$rlimit = $total_pages;
}
else
{
$rlimit = $window;
}
}
else
{
if(($page + floor($window/2)) > $total_pages)
{
if ($total_pages - $window < 0)
{
$llimit = 1;
}
else
{
$llimit = $total_pages - $window + 1;
}
$rlimit = $total_pages;
}
else
{
$llimit = $page - floor($window/2);
$rlimit = $page + floor($window/2);
}
}
if ($page>1)
{
$page_arr[$arr_count]['title'] = 'Prev';
$page_arr[$arr_count]['link'] = $url.$symb.'page='.($page-1);
$page_arr[$arr_count]['current'] = 0;
$arr_count++;
}
for ($x=$llimit;$x <= $rlimit;$x++)
{
if ($x <> $page)
{
$page_arr[$arr_count]['title'] = $x;
$page_arr[$arr_count]['link'] = $url.$symb.'page='.($x);
$page_arr[$arr_count]['current'] = 0;
}
else
{
$page_arr[$arr_count]['title'] = $x;
$page_arr[$arr_count]['link'] = $url.$symb.'page='.($x);
$page_arr[$arr_count]['current'] = 1;
}
$arr_count++;
}
if($page < $total_pages)
{
$page_arr[$arr_count]['title'] = 'Next';
$page_arr[$arr_count]['link'] = $url.$symb.'page='.($page+1);
$page_arr[$arr_count]['current'] = 0;
$arr_count++;
}
return $page_arr;
}
?>
and call it by
{LOOP: PAGES}{PAGES.title} {/LOOP: PAGES}
in an .html file..
it works perfectly but when I press the number 2 or next to get the next 20 records it jumps back to the first 20...
on the browser it reads http://siteurl/?cat=1&page=2
I can't figure out why.

Categories