I'm using the following code to apply a pagination to a large table in my database. It works fine however I can't figure out how to apply a WHERE Week="?" (52 weeks in the table) in the SELECT Query with the $start $limit variables. That way when I hit PREVIOUS or NEXT buttons it goes to the previous or next week of rows in that week.
<div id="content">
<?php
include("dbconfig.php");
$start=0;
$limit=10;
if(isset($_GET['id']))
{
$id=$_GET['id'];
$start=($id-1)*$limit;
}
else{
$id=1;
}
//Fetch from database first 10 items which is its limit. For that when
page open you can see first 10 items.
$query=mysqli_query($dbconfig,"select * from user LIMIT $start, $limit");
?>
<ul>
<?php
//print 10 items
while($result=mysqli_fetch_array($query))
{
echo "<li>".$result['username']."</li>";
}
?>
</ul>
<?php
//fetch all the data from database.
$rows=mysqli_num_rows(mysqli_query($dbconfig,"select * from user"));
//calculate total page number for the given table in the database
$total=ceil($rows/$limit);
if($id>1)
{
//Go to previous page to show previous 10 items. If its in page 1 then it is inactive
echo "<a href='?id=".($id-1)."' class='button'>PREVIOUS</a>";
}
if($id!=$total)
{
////Go to previous page to show next 10 items.
echo "<a href='?id=".($id+1)."' class='button'>NEXT</a>";
}
?>
<ul class='page'>
<?php
//show all the page link with page number. When click on these numbers go to particular page.
for($i=1;$i<=$total;$i++)
{
if($i==$id) { echo "<li class='current'>".$i."</li>"; }
else { echo "<li><a href='?id=".$i."'>".$i."</a></li>"; }
}
?>
</ul>
</div>
Your probably looking for a select box for the weeks, then use that value in your where clause.
<select name="weeks">
<?php
for( $i = 1; $i <= 52; $i++ ):
echo '<option name="week" value="'.$i.'"></option>';
endfor;
?>
</select>
The query:
$mysqli = dbConnect();
$stmt = $mysqli->prepare( $sql );
if( !empty( $_POST['weeks'] ) ):
$week = $_POST['week'];
// Validate the data
$week = trim( $week );
$week = htmlspecialchars( $week );
if( !ctype_digit( $week ) ):
echo 'Week is not a valid input';
else:
// Prepared statement
$sql = "SELECT * FROM user WHERE week = ? LIMIT ?, ?";
$stmt->bind_param("iii", $week, $start, $limit);
endif;
else:
$sql = "SELECT * FROM user LIMIT ?, ?";
$stmt->bind_param("ii", $start, $limit);
endif;
$stmt->execute();
$stmt->bind_result(yourparamshere);
$stmt->close();
$mysqli->close();
Note:
Please take a look at http://php.net/manual/en/pdo.prepared-statements.php
Prepared statements and stored procedures are much saver and will make you a better programmer.
Related
I am writing PHP script to display data from the database (Mysql) on my webpage. I don't want all the information to display on a single page to avoid scrolling. However, I want to display only a few and then use page numbers to navigate to the rest. I managed to create the page numbers and yet still all the information is showing on a single page. Below is my code:
<?php
include('./includes/DB_Config.php');
$status = 1;
// Set number of Post per page for navigation
$post_per_page = 2;
if (isset($_GET['page']))
{
$startP = ($_GET['page'] - 1) * $post_per_page;
}
else
{
$startP = 0;
}
$post = mysqli_query ($mySQL_Conn, "SELECT * FROM BlogPost WHERE status = '$status'");
// Fetch Data or number of rows
$dataRw = mysqli_num_rows($post);
$pages = $dataRw / $post_per_page;
if ($dataRw == 0)
{
$_SESSION['NoPost'] = "No Post Found!";
}
else
{
unset($_SESSION['NoPost']);
//$pages = ceil($dataRw / $rows_per_page);
//$pages = array_slice($dataRw, $startP, $post_per_page);
while ($data = mysqli_fetch_array($post)) //Fetch data in array
{
//Assign data to variabes
$name = $data['blogger_Name'];
$postDate = $data['dateTime'];
$blogpost = $data['blog_message'];
$date = strtotime($postDate);
?>
<p> <span><?php echo $_SESSION['NoPost'] ; ?> </span></p>
<p> <span>By:</span><?php echo $name; ?> </p>
<p> <span>Posted On: </span> <?php echo date("j F Y", $date); ?> </p>
<p> <span>Post: </span><?php echo $blogpost; ?> </p>
<?php
}
}
?>
<hr>
<?php
for ($currentpage = 0; $currentpage < $pages; $currentpage++ )
{
?>
<span> <?php echo $currentpage + 1; ?> </span>
<?php
}
?>
What you are trying to accomplish is a very common pattern, and it's called pagination.
You can use LIMIT and OFFSET in your mysql queries to get only a certain subset of the data, and you can use this for basic pagination.
For example, if you want to display 50 results per page, and the user is on the third page, you set LIMIT to 50 and OFFSET to 2*50 (100), keep in mind the first page is an offset of 0 so we subtract the page by one.
You can use the following sql query to get a subset of data for a specific page.
"SELECT * FROM Users LIMIT $num_results OFFSET ".(($page_num-1)*$num_results);
You can get the total number of possible pages by getting the total row count from the Users table and dividing it by $num_results. A good idea might be to have your output script take a GET url query parameter that will be used as the page number.
I am trying to filter details using a-z list, which I can do successfully.
But the problem I am facing is that when I want to display the result along with some pagination, it doesn't do exactly what I want it to do.
Here is my code:
<?php
session_start();
//what page are we currently on
if(!isset($_GET['page'])){
$page=1;
}
else {
$page=(int)$_GET['page'];
}
//select how many records to show per page
$limit=16;
//count how many rows
$total=$conn->query("SELECT COUNT(*) FROM `movie`")->fetchColumn();
//how many pages will be there
$pages=ceil($total/$limit);
if($page<1){
$page=1;//forcing page to be 1 if it is less then 1
}
else if($page>$pages){
$page=$pages;
}
//calculate the offset
$offset=($page-1)*$limit;
if(isset($_GET['word'])){
$qname=$_GET['word'];
}
else {
$qname='a';
}
$sql=$conn->prepare("SELECT * FROM `movie` WHERE `title` LIKE '$qname%' ORDER BY `movie_id` LIMIT $limit OFFSET $offset");
$sql->execute();
$sql->rowCount();
while($row=$sql->fetch(PDO::FETCH_ASSOC)){
$title=$row['title'];
$poster=$row['poster'];
echo '<li><a href="#">
<img src="'.$poster.'" />
<h2><strong>Watch '.$title.' Online</strong></h2>
</a>
</li>';
}
?>
Then somewhere in my html i have this pagination
<?php
$prev=$page-1;
$next=$page+1;
$previous="";
$nextr="";
if($page>1){
$previous='<li>«</span>';
}
if($page<$pages){
$nextr='<li>»</span>';
}
$numbers="";
if($pages>1){
for($i = max(1, $page - 5); $i <= min($page + 5, $pages); $i++){
if($i==$page){
$numbers.='<li><a class="active" href="?page='.$i.'">'.$i.'</a></span></li>';
}
else {
$numbers.='<li>'.$i.'</span></li>';
}
}
}
echo $previous;
echo $numbers;
echo $nextr;
?>
And my html :-
<div class="result"><h2>Browse By Words :- A | B</h2></div>
So when I click on link-a it displays the result and the url is like a-z.php?word=a and then when i try to paginate the url changes to a-z.php?page=2
So, how can I paginate the result after fetching it from the db?
I am looking for a way without ajax.
I have a problem with my pagination, I need your help please.
I have 53 records but with this pagination, I can get 50 records only, I can't see the 3 others
I want to change this code to get all records please, and if I want to make the pagination easy to navigate for big records. Like this (for exp):
<< 1 2 3 4 5 ...... 184 185 >>
Thanks
<?php
include("db.php"); //include config file
//sanitize post value
$page_number = filter_var($_POST["page"], FILTER_SANITIZE_NUMBER_INT, FILTER_FLAG_STRIP_HIGH);
//validate page number is really numaric
if(!is_numeric($page_number)){die('Invalid page number!');}
//get current starting point of records
$position = ($page_number * $item_per_page);
//Limit our results within a specified range.
$results = mysqli_query($db,"SELECT id,name,message FROM paginate ORDER BY id ASC LIMIT $position, $item_per_page");
//output results from database
while($row = mysqli_fetch_array($results))
{
echo' <ul class="page_result">
<li class="page_result_img"><img src="images/pic1.jpg" class="img-responsive" alt=""/></li>
<li class="page_result_desc" id="item_'.$row["id"].'">
<h3>'.$row["id"].'.'.$row["name"].'</h3>
<p>'.$row["message"].'</p>
</li>
<p class="no">'.$row["id"].'<br><span>projet</span></p>
<div class="clearfix"> </div>
</ul>';
}
?>
projet.php
<?php
include("db.php");
$results = mysqli_query($db,"SELECT COUNT(*) FROM paginate");
$get_total_rows = mysqli_fetch_array($results); //total records
//break total records into pages
$pages = ceil($get_total_rows[0]/$item_per_page);
//create pagination
if($pages > 1)
{
$pagination = '';
$pagination .= '<ul class="paginate">';
for($i = 1; $i<$pages; $i++)
{
$pagination .= '<li>'.$i.'</li>';
}
$pagination .= '</ul>';
}
?>
.
.
.
.
<div class="approach" id="app">
<div class="container">
<div class="gallery-head text-center">
<h3>Nos projets</h3>
<p>Trouvez ici tout les projets</p>
<span> </span>
</div>
<ul id="results"></div>
<?php echo $pagination; ?>
</div>
</div>
For correct LIMIT in SQL query must be value of $page_number for the first page equal to 0. But your pagination starts from 1. Then you never get $position = 0 and SQL query skips first $item_per_page records.
Try modify $position calculation:
$position = (($page_number - 1) * $item_per_page);
Second problem is in projet.php. For 53 records (and $item_per_page = 10) is value of $pages = 6. But for cycle stops on 5. It should be:
for($i = 1; $i <= $pages; $i++)
I like to work this way .. So try this code hope it help
$results = mysqli_query($db,"SELECT * FROM paginate");
$get_total_rows = mysqli_num_rows($results); //total records
$item_per_page = 10;
//break total records into pages
$pages = ceil($get_total_rows/$item_per_page);
//create pagination
if($pages > 1)
{
?>
<ul class="paginate">
<?php
for($i = 1; $i<$pages; $i++)
{
if($pages <= 5){
?>
<li><?php echo $i; ?></li>
<?php
}elseif($pages >= $pages - 5){
?>
<li><?php echo $i; ?></li>
<?php
}
}
?>
</ul>
<?php
}
Hey, I am still trying to allow multiple filters to be selected for my pagination script but not sure how to do it being very new to php and programing in general.
So in my pagination, when a user clicks the 'marketing' button(link) it queries the database just for the category that = marketing. The same goes for the other 2 filter buttons as seen in the script below. (automotive, sports).
The problem is, I want to be able to select multiple filters like only marketing and auomotive or automotive and sports, for example if I click the marketing filter and then the automotive, it would display the categories that equal marketing, and automotive.
I have no idea how to accomplish this, so I have come to the experts to help me out.
This is the script I am working on:
<h3>Filter results by:</h3>
<a href='pagi_test.php?category=marketing'>marketing</a>
<a href='pagi_test.php?category=automotive'>automotive</a>
<a href='pagi_test.php?category=sports'>sports</a>
<br />
<h3>Results:</h3>
<?php
//connecting to the database
$error = "Could not connect to the database";
mysql_connect('localhost','root','root') or die($error);
mysql_select_db('ajax_demo') or die($error);
//max displayed per page
$per_page = 3;
//get start variable
$start = $_GET['start'];
$category = mysql_real_escape_string($_GET['category']);
//count records
$record_count = mysql_num_rows(mysql_query("SELECT * FROM explore WHERE category='$category'"));
//count max pages
$max_pages = $record_count / $per_page; //may come out as decimal
if (!$start)
$start = 0;
//display data
$get = mysql_query("SELECT * FROM explore WHERE category='$category' LIMIT $start, $per_page");
?>
<table width="800px">
<?php
while ($row = mysql_fetch_assoc($get))
{
// get data
$id = $row['id'];
$site_name = $row['site_name'];
$site_description = $row['site_description'];
?>
<tr>
<td><?php echo $id; ?></td>
<td><?php echo $site_name; ?></td>
<td><?php echo $site_description; ?></td>
</tr>
<?php
}
//setup prev and next variables
$prev = $start - $per_page;
$next = $start + $per_page;
//show prev button
if (!($start<=0))
echo "<a href='pagi_test.php?category=$category&start=$prev'>Prev</a> ";
//show page numbers
//set variable for first page
$i=1;
for ($x=0;$x<$record_count;$x=$x+$per_page)
{
if ($start!=$x)
echo " <a href='pagi_test.php?category=$category&start=$x'>$i</a> ";
else
echo " <a href='pagi_test.php?category=$category&start=$x'><b>$i</b></a> ";
$i++;
}
//show next button
if (!($start>=$record_count-$per_page))
echo " <a href='pagi_test.php?category=$category&start=$next'>Next</a>";
?>
Any help on this would be great. Thank you.
-- EDIT --
If anyone has a better method of doing a pagination system with multiple filters than the one above, please let me know.
While selecting second filter u can add the category
ex:
At first ur variable $category has
$category="Marketing";
When user filter with another category suppose automotive then add it to $category with a delimeter,Now
$category="Marketing:Automotive";
when u access thru GET use explode:
$cat=explode(":",$_GET['category']);
and write your condition
$condition="category=category[0]";
for($i=1; $i<sizeof($cat); $i++)
{
$condition="AND category=$cat[$i]";
}
$where="WHERE $condition";
use $where in ur query, like
$record_count = mysql_num_rows(mysql_query("SELECT * FROM explore $where"));
I see two separate issues
How to allow the user to select more than one category to filter by
How to propagate those choices to the pagination links
Each for which I have a solution!
How to allow the user to select more than one category to filter by
A form is going to be the most direct approach.
<h3>Filter results by:</h3>
<form action="pagi_test.php" method="GET">
<input type="checkbox" name="category[]" value="marketing" id="cat_marketing"/>
<label for="cat_marketing">Marketing</label>
<br/>
<input type="checkbox" name="category[]" value="automotive" id="cat_automotive"/>
<label for="cat_automotive">Automotive</label>
<br/>
<input type="checkbox" name="category[]" value="sports" id="cat_sports"/>
<label for="cat_sports">Marketing</label>
<br/>
<input type="submit" value="Filter!" />
</form>
Now, $_GET['category'] will be an array of every category that was selected.
$categories = $_GET['category'];
$inClause = "'" . implode( "','", array_map( 'mysql_real_escape_string', $categories ) ) . "'";
//count records
$record_count = mysql_num_rows(
mysql_query( "SELECT * FROM explore WHERE category IN($inClause)" )
);
Of course, you'd probably want to add a check here to make sure $categories isn't empty before you execute the query.
You'll need to modify the actual selection query as well
//display data
$get = mysql_query("SELECT * FROM explore WHERE category IN($inClause) LIMIT $start, $per_page");
Bingo! Now that part is done!
How to propagate those choices to the pagination links
Since we already have an array of the categories selected stored in $categories, this will be trivial using http_build_query().
//setup prev and next variables
$prev = $start - $per_page;
$next = $start + $per_page;
// Get the categories in an HTML-safe array
$requestVars = array_map( 'htmlspecialchars', $categories );
//show prev button
if (!($start<=0))
{
$requestVars['start'] = $prev;
echo 'Prev ';
}
//show page numbers
//set variable for first page
$i=1;
for ( $x = 0; $x < $record_count; $x = $x + $per_page )
{
$requestVars['start'] = $x;
if ( $start != $x )
{
echo ''. $i .' ';
} else {
echo '<b>'. $i .'</b> ';
}
$i++;
}
//show next button
if (!($start>=$record_count-$per_page))
{
$requestVars['start'] = $next;
echo 'Next ';
}
Now, there are still holes in this implementation.
Since the <form> is printed to the page before the rest of the logic, there's no way to pre-select the checkboxes that represent the current filter choices. Which you could definitely change.
Also, you have categories as literal strings in the PHP script - they would really be better in their own table in the database.
The way you retrieve a count for the entire data set is inefficient - it sends the entire data set over the wire to PHP, which then is responsible for determining the record count. It's much better to run a separate query that uses SELECT count(*) ... instead.
hello i want to list contents as 10 contents per page
this is source code for each content
<?
while ($arama=mysql_fetch_array($arama_sonuc)) {
?>
<h4><?=$arama[baslik]?></h4>
<div class="article box">
<div class="article-desc-oku">
<p class="info">Yayınlanma: <strong><?=$arama[eklemetarihi]?></strong><br />
Yazan: <strong>Ronnie C. Lynwood</strong><br /><?=$arama[tiklanma]?> kez okunmuş.<br />
<?php rating_form("$arama[id]"); ?>
</p>
</div>
<?=$arama[spot]?>
</div> <!-- /article -->
I think you should better use a paging class rather than creating your own. This will save a lot of time of yours in next projects too. Your current problem will also be solved. Check this out.
Download Location
It looks like you are using MySQL: You can build a query using the SQL LIMIT command.
For example:
SELECT * FROM myTable LIMIT 5, 10
Will tell MySQL to return only the first ten elements after the 5th row. You can use a parameter on the query string to build an appropriate SQL query to "ask" the database which "page" you want to see.
Here http://php.about.com/od/phpwithmysql/ss/php_pagination.htm you can find a complete code example on pagination. It's also explained very well.
Sorry but I can't offer more just by seeing a snipped of code ...
i used codes below to make pagination
<?
if (isset($_GET['sayfa'])) {
$pageno = $_GET['sayfa'];
} else {
$pageno = 1;
} // if
$query = mysql_query("SELECT count(id) FROM yazilar");
$query_data = mysql_fetch_row($query);
$numrows = $query_data[0];
$rows_per_page = 10;
$lastpage = ceil($numrows/$rows_per_page);
$pageno = (int)$pageno;
if ($pageno > $lastpage) {
$pageno = $lastpage;
} // if
if ($pageno < 1) {
$pageno = 1;
} // if
$limit = 'ORDER BY id DESC LIMIT ' .($pageno - 1) * $rows_per_page .',' .$rows_per_page;
$query = mysql_query("SELECT * FROM yazilar $limit");
if ($pageno == 1) {
echo " İLK ÖNCEKİ ";
} else {
echo " <a href='{$_SERVER['PHP_SELF']}?sayfa=1'>İLK</a> ";
$prevpage = $pageno-1;
echo " <a href='{$_SERVER['PHP_SELF']}?sayfa=$prevpage'>ÖNCEKİ</a> ";
} // if
echo " ( Sayfa $pageno ) ";
if ($pageno == $lastpage) {
echo " SONRAKİ SON ";
} else {
$nextpage = $pageno+1;
echo " <a href='{$_SERVER['PHP_SELF']}?sayfa=$nextpage'>İLERİ</a> ";
echo " <a href='{$_SERVER['PHP_SELF']}?sayfa=$lastpage'>SON</a> ";
} // if
?>
Let me suggest some existing PHP solutions
Zend_Paginator, loosely coupled can be used stand alone without the whole framework.
If you want to build your own flavour I recommand the SPL countable and Iterator classes.