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
Related
Im trying to create pagination using PHP but I have issue with quantity of page.
my pagination created used
foreach(range(1, $pager) as $i){
echo '<span class="pagination-num" data-pager="'.$i.'">'.$i.'</span>';
}
the problem comes when the range is too large. like on the image below. variable $pager contains a dynamic value. $pager counts how many pages should created from quantity of the content.
I set 10 content per page, so if there is 100 content:
$pager = ceil($content / 10);
it's there any way to edit pagination with dots. (next and prev I created using custom Jquery).
first of all you need to set items per page for example 10 items per page
<?php
$ipp = 10; //Item Per Page
if(isset($_GET["page"]) AND $_GET["page"] > 0){
$page_number = $_GET['page']; // page number
}
else{$page_number = 1;}
$total_items = 100; //total items
$total_pages = ceil($total_items/$ipp); //total pages
$page_position = (($page_number-1) * $ipp); //page position
?>
just in case if you are using sql:
"SELECT * FROM `table` WHERE --something-- ORDER BY `id` ASC LIMIT {$page_position}, {$ipp}"
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;
}
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.
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
Is it possible to create pagination without getting all elements of table?
But with pages in GET like /1 /666…
It usually involves issuing two queries: one to get your "slice" of the result set, and one to get the total number of records. From there, you can work out how many pages you have and build pagination accordingly.
A simply example:
<?php
$where = ""; // your WHERE clause would go in here
$batch = 10; // how many results to show at any one time
$page = (intval($_GET['page']) > 0) ? intval($_GET['page']) : 1;
$start = $page-1/$batch;
$pages = ceil($total/$batch);
$sql = "SELECT COUNT(*) AS total FROM tbl $where";
$res = mysql_query($sql);
$row = mysql_fetch_assoc($res);
$total = $row['total'];
// start pagination
$paging = '<p class="paging">Pages:';
for ($i=1; $i <= $pages; $i++) {
if ($i==$page) {
$paging.= sprintf(' <span class="current">%d</a>', $i);
} else {
$paging.= sprintf(' %1$d', $i);
}
}
$paging.= sprintf' (%d total; showing %d to %d)', $total, $start+1, min($total, $start+$batch));
And then to see your pagination links:
...
// loop over result set here
// render pagination links
echo $paging;
I hope this helps.
Yes, using mySQL's LIMIT clause. Most pagination tutorials make good examples of how to use it.
See these questions for further links and information:
How do you implement pagination in PHP?
Searching for advanced php/mysql pagination script
more results
You can use LIMIT to paginate over your result set.
SELECT * FROM comments WHERE post_id = 1 LIMIT 5, 10
where LIMIT 5 means 5 comments and 10 is the offset. You can also use the longer syntax:
... LIMIT 5 OFFSET 10