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
Related
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;
}
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
I'm creating a new website, I don't want to link direct to it so I'll put spaces inbetween:
test . glow - sticks . org
I have a list of the 15 most popular products on the right hand side of the page (WHATS HOT), I would like to show a number for each one, the first being 1 and the last being 15.
I am a php noob, but despite reading about using range and foreach at the php manual site, I'm struggling to show numbers. I've found it easy to show the same range of numbers for each product block, e.g 1,2,3...15 showing 15 times, but this obviously isn't what I'm trying to do.
I probably need to give more info than I have here, so I'll past the code that I'm working with on the php include:
<div id="whatshot_smallblock">
<a href='/<?=str_replace(" ","-",$productname)?>.html'><img src='http://www.glow-sticks.org/images/products/<?=$productimage?>' alt='<?=$productname?>' width='66' height='66' hspace="2" vspace="2" border='0' class="radius" />
</a>
<div id="whatshot_smallblock_Txt">
<a href='/<?=str_replace(" ","-",$productname)?>.html'><?=$productname?></a><br><div id="pink_color"><span class="content_2"><?=$minprice_dis?></span><?=$_SESSION['currsymbol']?><?=$minprice?></div></div>
<div id="bigblacknumbers"></div></div>
and in my objectmanager php file I can see the code relating to the whatshot section:
//what's hot
function whatshotids() {
if( !isset( $this->dblink ) )
dbconnect();
//$sql = "SELECT COUNT(pid) AS repetitions, pid FROM gs_orderlines GROUP BY pid ORDER BY repetitions DESC LIMIT 15";
$timenow = time();
$checktime = ($timenow - 1814400); // 3 weeks
$sql = "SELECT COUNT(pid) AS repetitions, gs_orderlines.pid FROM gs_orderlines INNER JOIN gs_orders ON gs_orders.oid =
gs_orderlines.oid WHERE gs_orders.datetime >= $checktime GROUP BY gs_orderlines.pid ORDER BY repetitions DESC LIMIT 15";
$result = mysql_query( $sql, $this->dblink )
or die( "Invalid query Line 1018" );
$i = 0;
$whids = array();
while( $row = mysql_fetch_object( $result ) ) {
////
$sql2 = "SELECT * from gs_inventory WHERE pid = ".$row->pid. " AND display_product='1' AND stock>0 AND canbackstock!='yes'";
$result2 = mysql_query( $sql2, $this->dblink );
if($row2 = mysql_fetch_object( $result2 )){
$whids[$row->pid] = $row->repetitions;
$i = $i + 1;
}
...
}
...
}
Hopefully this is enough or too much information.
Many thanks!
What about:
<?php
$i=1;
foreach($products as $product) { ?>
<div id="whatshot_smallblock">
<?php echo $i; ?><a href='/<?=str_replace(" ","-",$productname)?>.html'><img src='http://www.glow-sticks.org/images/products/<?=$productimage?>' alt='<?=$productname?>' width='66' height='66' hspace="2" vspace="2" border='0' class="radius" />
</a>
<div id="whatshot_smallblock_Txt">
<a href='/<?=str_replace(" ","-",$productname)?>.html'><?=$productname?></a><br><div id="pink_color"><span class="content_2"><?=$minprice_dis?></span><?=$_SESSION['currsymbol']?> <?=$minprice?></div></div>
<div id="bigblacknumbers"></div></div>
<?php
$i++;
} ?>
So, basically, just loop through your products and echo $i (a number that gets +1 on each iteration)....
With the code you have included its difficult to see how you output your HTML ... the 2 pieces of code look very disconnected ...
To do what you want you could just use an incremental count in your while loop :
$num = 1;
while( $row = mysql_fetch_object( $result ) ) {
echo "Product Number = " . $num;
$num++; // increment
// do what every else you need
}
The problem is - you are not outputting any code in your PHP ... if you update your question it might help
It seemed that the only thing I needed to do was to enter:
<?$counter++; echo $counter;?>
And it just started counting from the first iteration.
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)
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