PHP Pagination with SQL_CALC_FOUND_ROWS and LIMIT - php

Hello my dear friends,
My goal is to paginate through my database entries, while using SQL_CALC_FOUND_ROWS and FOUND_ROWS, because I also have a search function
The search results are there, I just cannot paginate through them.
Probably my code is a total mess for the PHP Pros here, please don’t worry about commenting on that. Any help is greatly appreciated. I am just starting out on PHP and I am highly motivated to become a Pro one day as well.
What is it that I have to do in order to make the pagination work, so that I can paginate while having a search function on the page?
DETAILS:
check for the page
get the search
SEARCH FORM submit to same page
pagination and search are meant to work in unity
LIMIT in conjunction with SQL_CALC_FOUND_ROWS
LIKE to filter search results
prepared statements
while loop displays results with PDO fetch
FOUND_ROWS to get result of first query
--> that result is an Integer
last page is calculated by dividing
that Integer through the limit
pagination is done inside for loop with if statements
connect
try {
$conn = new PDO($server, $user, $pass);
$conn -> setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$conn -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// echo "success";
} catch (PDOException $e) {
echo "ERROR: " . $e -> getMessage();
}
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL & ~E_NOTICE);
index
if (!isset($_GET['page'])) { $page = 1;
} else { $page = $_GET['page']; }
if ($page < 1) { $page = 1;
} elseif ($page > $last_page) {
$page = $last_page; }
$search = $_GET['search'];
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form action="<?php $_SERVER['PHP_SELF'] ?>" method="GET">
<input type="text" name="search" value="<?php $search ?>">
<input type="submit" value="search">
</form</body>
</html>
<?php
$start = 0;
$limit = 3;
$query = "
SELECT SQL_CALC_FOUND_ROWS * FROM tbl_articles
WHERE
(art_headline LIKE '%{$search}%')
OR
(art_content LIKE '%{$search}%')
LIMIT $start, $limit
";
$stmt = $conn -> prepare($query);
$stmt -> execute();
while ($res = $stmt -> fetch(PDO::FETCH_ASSOC)) {
echo '<h1>'.$res['art_headline'].'</h1>'."\n";
echo '<p>'.$res['art_content'].'</p>';
echo '<b>'.$res['art_author'].'</b>'."\n";
echo '<span>'.date("d.m.Y", strtotime($res['art_datetime'])).'</span>'."\n\n";
echo '<b>'.$res['art_id'].'</b>'."\n";
}
$query = "
SELECT FOUND_ROWS() AS num FROM tbl_articles
";
$stmt = $conn -> prepare($query);
$stmt -> execute();
$max = $stmt -> fetch(PDO::FETCH_ASSOC);
var_dump($max[num]);
$total_pages = $max[num];
// $stmt = $conn -> query($query) -> fetchColumn();
$last_page = ceil($total_pages / $limit);
// loop through pages
echo "<div><nav>";
for ($i = 1; $i <= $last_page; $i++) {
if (
($i == 1)
||
($i == $last_page)
||
(
($i >= ($page - 2))
&&
($i <= ($page + 2))
)
) {
if ($last_i != ($i - 1)) {
$out .= " ... ";
}
if ($page == $i) { $out .= "["; }
$out .= "$i";
if ($page == $i) { $out .= "] "; }
$out .= " ";
$last_i = $i;
$prev = $page - 1;
$prev_link = "back\n";
$next = $page + 1;
$next_link = "next\n";
}
}
echo $prev_link;
echo $out;
echo $next_link;
echo "</nav></div>";
?>
Any help is greatly appreciated, from a PHP beginner.

ok guys, my PHP Pro Mentor helped me solve it.
Here we go:
to fix the search results display I had to insert
if ($_GET['page'] > 1) {
$start = ($_GET['page'] - 1) * $limit;
}
between the $start and $limit variables and the first $query
to fix the pagination I just had to insert:
$page = $_GET['page'];
on top of the script.

Related

Problems with php pagination function

I have two php files:
1. functions.php
2. index.php
The functions.php file has a series of functions that query MySQL database to produce different result sets. For example, i have two functions; one that returns all data whose year 2016, and the other that returns all the data whose year is 2015.
For both queries i desire to have php pagination for the result sets returned. An example of the function that returns results for all data whose years are 2015 and 2016 looks like this:
function get2015(){
$con = dbConnect();
$refs_per_page = 20;
$query = "select * from mytable where year = 2015";
$sql=$con->prepare($query);
$sql->execute();
$total = $sql->rowCount();
$pages = ceil($total/$refs_per_page);
echo "$total <br>";
if (isset($_GET['page']) && is_numeric($_GET["page"])){
$page = (int) $_GET['page'];
}//endif
if($page =="" || $page ==1){
$page=0;
}
else{
$page = ($page * $refs_per_page)-$refs_per_page;
}
//
$query = "select * from mytable where year = 2015 limit $page, $refs_per_page";
$sql=$con->prepare($query);
$sql->execute();
$sql->setFetchMode(PDO::FETCH_ASSOC);
while ($row=$sql->fetch()){
$title = $row['title'];
$authors = $row['authors'];
echo "<b>$title</b>" . "<br>" . $authors . "<p>";
}
//
for($x=1; $x<=$pages; $x++){
?> <?php echo $x;?> <?php
}
}
//function get records for 2016
function get2016(){
$con = dbConnect();
$refs_per_page = 20;
$query = "select * from mytable where year = 2016";
$sql=$con->prepare($query);
$sql->execute();
$total = $sql->rowCount();
$pages = ceil($total/$refs_per_page);
echo "$total <br>";
if (isset($_GET['page']) && is_numeric($_GET["page"])){
$page = (int) $_GET['page'];
}//endif
if($page =="" || $page ==1){
$page=0;
}
else{
$page = ($page * $refs_per_page)-$refs_per_page;
}
//
$query = "select * from mytable where year = 2016 limit $page, $refs_per_page";
$sql=$con->prepare($query);
$sql->execute();
$sql->setFetchMode(PDO::FETCH_ASSOC);
while ($row=$sql->fetch()){
$title = $row['title'];
$authors = $row['authors'];
echo "<b>$title</b>" . "<br>" . $authors . "<p>";
}
//
for($x=1; $x<=$pages; $x++){
?> <?php echo $x;?> <?php
}
}
The code in index.php code looks like this
<?php
include "functions.php";
$page = $_GET["page"];
if($page){
if($page=="get2015"){
get2015();
}
if($page=="get2016"){
get2016();
}
}
?>
<html>
Archive<br>
2015<br>
2016<br>
</html>
<?php ?>
The first page renders okay but when i click on the second page the page goes blank. #Syed below has suggested the use of an offset variable, which while useful does the same thing as the $page variable in the code above. How do i get pagination to work? I highly suspect that the problem is how i am calling the pages on index.php
Your sould make $offset variable and minus 1 from it and then multiply by $per_page
For example
User in index.php your offset variable calculate like that.
// offset should be equal to 0 and query should be
// SELECT * FROM your_table WHERE year='2015' LIMIT 0, 20
(page=1 - 1) = 0 * $per_page = 20
User in index.php?page=2 your offset variable calculate like that.
// offset should be equal to 20 and query should be
// SELECT * FROM your_table WHERE year='2015' LIMIT 20, 20
(page=2 - 1) = 1 * $per_page = 20
// offset should be equal to 40 and query should be
// SELECT * FROM your_table WHERE year='2015' LIMIT 40, 20
(page=3 - 1) = 2 * $per_page = 40
$sql = sprintf("SELECT COUNT(*) FROM your_table WHERE year='%s'", $_GET['year']);
// Query to database and store in pages variable
$total_record = $con->query($sql)->result();
$page = ( isset($_GET['page']) && is_numeric($_GET['page'])) ? $_GET['page'] : 1;
$per_page = 20;
$offset = ($page - 1) * $per_page;
$pages = ceil($total/$per_page);
$sql = sprintf("SELECT * FROM your_table WHERE year='%s' LIMIT %s, %s", $_GET['year'], $offset, $per_page);
// QUERY TO DATABASE
for($i=1; $i<=$pages; $i++){
if ($page == $i) {
echo '<span class="active">'. $i .'</span>';
}else{
echo '' .$i .'';
}
}

PHP For loop issue with Mysqli

I'm trying to get this PHP script to paginate the data pulled from the mysql database.
It is going wrong somewhere in the second for loop. Instead of pulling the data through it is just returning blank or empty fields.
I need it to display the title, description and content fields from the database, along with the ID.
require_once("../controls/config.php");
$connection = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
if ($connection->connect_errno) {
printf("Connect failed: %s\n", $connection->connect_error);
exit();
}
// number of results to show per page
$per_page = 3;
// figure out the total pages in the database
$result = $connection->query("SELECT * FROM pages");
$total_results = $result->num_rows;
$total_pages = ceil($total_results / $per_page);
// check if the 'page' variable is set in the URL (ex: view-paginated.php?page=1)
if (isset($_GET['page']) && is_numeric($_GET['page']))
{
$show_page = $_GET['page'];
// make sure the $show_page value is valid
if ($show_page > 0 && $show_page <= $total_pages)
{
$start = ($show_page -1) * $per_page;
$end = $start + $per_page;
}
else
{
// error - show first set of results
$start = 0;
$end = $per_page;
}
}
else
{
// if page isn't set, show first set of results
$start = 0;
$end = $per_page;
}
for ($i = 1; $i <= $total_pages; $i++)
{
echo "<a href='?page=$i'>$i</a><br>";
}
// loop through results of database query, displaying them in the table
for ($i = $start; $i < $end; $i++)
{
// make sure that PHP doesn't try to show results that don't exist
if ($i == $total_results) { break; }
echo $i["id"].' ';
echo $i["title"].' ';
echo $i["description"].' ';
echo $i["content"].' ';
echo 'Edit ';
echo 'Delete<br>';
}
?>
<p>Add a new record</p>
Can anyone point me in the right direction?
It looks like you are trying to treat $i as an associative array. Though $i is only a integer. Additionally, you do not have an array the contains the results from your mysqli query. You should try:
// this will loop through results and assign to $rows array
while($row = $result->fetch_array())
{
$rows[] = $row;
}
// this will loop through $rows array and provide each column result
foreach($rows as $row)
{
echo $row["id"];
echo $row["title"];
echo $row["description"];
echo $row["content"];
}
For further information please refer to: http://us2.php.net/mysqli_fetch_array

display 5 result per page

I'm new to this, and was hoping someone may be able to help me, I have a mysql database with 4 fields "id, date, name, comment"
I have the following php file:
<html>
<head>
<title>Paging Using PHP</title>
</head>
<body>
<?php
$dbhost = 'localhost';
$dbuser = 'USERNAME';
$dbpass = 'PASSWORD';
$rec_limit = 5;
$conn = mysql_connect($dbhost, $dbuser, $dbpass);
if(! $conn )
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db('DATABASE_NAME');
/* Get total number of records */
$sql = "SELECT count(id) FROM comments ";
$retval = mysql_query( $sql, $conn );
if(! $retval )
{
die('Could not get data: ' . mysql_error());
}
$row = mysql_fetch_array($retval, MYSQL_NUM );
$rec_count = $row[0];
if( isset($_GET{'page'} ) )
{
$page = $_GET{'page'} + 1;
$offset = $rec_limit * $page ;
}
else
{
$page = 0;
$offset = 0;
}
$left_rec = $rec_count - ($page * $rec_limit);
$sql = "SELECT * FROM comments ORDER BY id DESC";
"FROM comments ".
"LIMIT $offset, $rec_limit";
$retval = mysql_query( $sql, $conn );
if(! $retval )
{
die('Could not get data: ' . mysql_error());
}
while($row = mysql_fetch_array($retval, MYSQL_ASSOC))
{
echo "<strong>Date :{$row['date']} </strong><br> ".
"<strong>Name : {$row['name']} </strong><br> ".
"Comment : {$row['comment']} <br> ".
"<br><br>";
}
if( $page > 0 )
{
$last = $page - 2;
echo "Previous Page |";
echo "Next Page";
}
else if( $page == 0 )
{
echo "Next Page";
}
else if( $left_rec < $rec_limit )
{
$last = $page - 2;
echo "Previous Page";
}
mysql_close($conn);
?>
This all works fine, apart from I want it do display 5 results per page, can someone please tell me what I need to change, how and where?
Many thanks
This is working code. Just copy and paste. Do your echo. It will look nice if you echo it in table.
<?php
//DB CONNECTION HERE
$currentPage = $_SERVER["PHP_SELF"];
$rec_limit = 5;//This will display 5 result per page
$pageNum_view = 0;
if (isset($_GET['pageNum_view'])) {
$pageNum_view = $_GET['pageNum_view'];
}
$startRow_view = $pageNum_view * $rec_limit;
mysql_select_db($dbhost, $dbuser, dbpass);
$query_view = "SELECT * FROM comments ORDER BY id DESC";
$query_limit_view = sprintf("%s LIMIT %d, %d", $query_view, $startRow_view, $rec_limit);
$view = mysql_query($query_limit_view, $dbconnect) or die(mysql_error());
$row_view = mysql_fetch_assoc($view);
if (isset($_GET['totalRows_view'])) {
$totalRows_view = $_GET['totalRows_view'];
} else {
$all_view = mysql_query($query_view);
$totalRows_view = mysql_num_rows($all_view);
}
$totalPages_view = ceil($totalRows_view/$rec_limit)-1;
$queryString_view = "";
if (!empty($_SERVER['QUERY_STRING'])) {
$params = explode("&", $_SERVER['QUERY_STRING']);
$newParams = array();
foreach ($params as $param) {
if (stristr($param, "pageNum_view") == false &&
stristr($param, "totalRows_view") == false) {
array_push($newParams, $param);
}
}
if (count($newParams) != 0) {
$queryString_view = "&" . htmlentities(implode("&", $newParams));
}
}
$queryString_view = sprintf("&totalRows_view=%d%s", $totalRows_view,
$queryString_view);
?>
//Here echo
<?php if ($pageNum_view > 0) { // Show if not first page ?>
<a href="<?php printf("%s?pageNum_view=%d%s", $currentPage, 0,
$queryString_view); ?>">FIRST</a>
<?php } // Show if not first page ?>
<?php if ($pageNum_view > 0) { // Show if not first page ?>
PREVIOUS
<?php } // Show if not first page ?>
<?php if ($pageNum_view < $totalPages_view) { // Show if not last page ?>
NEXT
<?php } // Show if not last page ?>
<?php if ($pageNum_view < $totalPages_view) { // Show if not last page ?>
LAST
<?php } // Show if not last page ?>
<?php
mysql_free_result($view);
?>

Passing Multiple Variables Through Pages PHP MYSQL

The following code is working fine for the first page. It is a query based on user input from a form. I have 2 issues. The first one is when i click next page i get undefined index and undefined variable error which means the variables are not passed. The second question is how can i make a query and paginate it based on the user filled/selected values in the form? Some users may not fill all the values.
Here is my code: NB: The form method is GET. I have tried REQUEST and POST too. All the same error. Thanks in advance guys.
<?php
if (isset($_POST['Submit']))
$name = mysql_real_escape_string($_GET['name']);
$email = mysql_real_escape_string($_GET['email']);
$age = mysql_real_escape_string($_GET['age']);
$height = mysql_real_escape_string($_GET['height']);
include_once "conn.php"; //connect to db and table
$rs = mysql_query("SELECT COUNT(*) FROM people WHERE name='$name' AND email='$email' AND age='$age' AND height='$height'");
$rw = mysql_fetch_array($rs);
$numrows = $rw[0];
if ($numrows== 0) die("No Results Found");
$rowsperpage = 7;
$totalpages = ceil($numrows / $rowsperpage);
if (isset($_GET['currentpage']) && is_numeric($_GET['currentpage'])) {
$currentpage = (int) $_GET['currentpage'];
} else {
$currentpage = 1;
}
if ($currentpage > $totalpages) {
$currentpage = $totalpages;
}
if ($currentpage < 1) {
$currentpage = 1;
}
$offset = ($currentpage - 1) * $rowsperpage;
$query = mysql_query("SELECT * FROM people WHERE name='$name' AND email='$email' AND age='$age' AND height='$height' ORDER BY time DESC LIMIT $offset, $rowsperpage");
//print my tables here
while($row = mysql_fetch_array($query))
{
$uniqueid = $row['age'];
//output stuff here
}
//close sql
$range = 3;
if ($currentpage > 1) {
echo " <a href='{$_SERVER['PHP_SELF']}?currentpage=1&name=$name&email=$email&age=$age&height=$height'> Go To Page 1</a> ";
$prevpage = $currentpage - 1;
echo "<a href='{$_SERVER['PHP_SELF']}?currentpage=$prevpage&name=$name&email=$email&age=$age&height=$height'> Previous Page</a>";
}
for ($x = ($currentpage - $range); $x < (($currentpage + $range) + 1); $x++) {
if (($x > 0) && ($x <= $totalpages)) {
if ($x == $currentpage) {
echo " <font size=4 color=red>[<b>$x</b>] </font>";
} else {
echo "<a href='{$_SERVER['PHP_SELF']}?currentpage=$x&name=$name&email=$email&age=$age&height=$height'>$x</a>";
}
}
}
if ($currentpage != $totalpages) {
$nextpage = $currentpage + 1;
echo "<a href='{$_SERVER['PHP_SELF']}?currentpage=$nextpage&name=$name&email=$email&age=$age&height=$height'>Next Page</font></a>";
echo "<a href='{$_SERVER['PHP_SELF']}?currentpage=$totalpages&name=$name&email=$email&age=$age&height=$height'>Last Page</a> ";
}
?>
The form submits as GET. Because this one, the POST variable isn't set. And you're not defining the first variable (missing brackets?). Furthermore, Submit is the only submitted value with a capital. Is this intentional?
if (isset($_GET['Submit'])) {
$name = mysql_real_escape_string($_GET['name']);
$email = mysql_real_escape_string($_GET['email']);
$age = mysql_real_escape_string($_GET['age']);
$height = mysql_real_escape_string($_GET['height']);
}
More ideally, because you want to ommit values, you'll probably want to check each variable individually for existence. And if it's not set (or empty), don't add that field in your WHERE clause.
$name = isset($_GET['name']) ? mysql_real_escape_string($_GET['name']) : null;
// ... process the other fields in same way ...
or spanned over multiple lines: EDIT: just noticed I was missing a closing ) in the two blocks below.
$name = null;
if (isset($_GET['name'])) {
$name = mysql_real_escape_string($_GET['name']);
}
// ... process the other fields in same way ...
or even:
$name = null;
if (isset($_GET['name']))
$name = mysql_real_escape_string($_GET['name']);
// ... process the other fields in same way ...
Dynamic query
Then, make your query a bit more dynamic. Like, adding all your available WHERE parameters to an array. It makes things easier.
// Store conditions in array
$whereConditions = array();
if (!empty($name)) {
$whereConditions['name'] = $name;
}
if (!empty($email)) {
$whereConditions['email'] = $email;
}
if ($age && $age > 0) {
$whereConditions['age'] = $age;
}
if ($height && $height > 0) {
$whereConditions['height'] = $height;
}
// Start building your query dynamically
$query = 'SELECT * FROM people';
// Making things easier here. Just flatten your array down.
$conditions = array();
foreach ($whereConditions as $field => $value) {
$conditions[] = sprintf("%s = '%s'", $field, $value);
}
// Join all conditions with AND
$where = implode(' AND ', $conditions);
// Add where clause, if there are conditions
if (!empty($where)) {
$query .= ' WHERE ' . $where;
}
$query .= " ORDER BY time DESC LIMIT {$offset}, {$rowsperpage}";
Final notes
Keep in mind to use prepared queries if you're allowing user input. And the mysql_ extension is deprecated. Switch to mysqli_ or PDO.

make this code PDO friendly

I've just started using PDO instead of the mysql functions. But now I'm stuck on a part of my php blog.
How would I make this code a little more PDO friendly:
$total_results = mysql_fetch_array(mysql_query("SELECT COUNT(*) as num
FROM php_blog"));
$total_pages = ceil($total_results['num'] / $blog_postnumber);
for($i = 1; $i <= $total_pages; $i++) {
if ($page == $i) {
echo "<span class='current'>$i</span>";
}
else {
echo "$i";
}
}
I tried with PDO rowCount(), but it doesn't seem to work...
Sorry for my poor english, I'm from Sweden!
rowCount doesn't work with mySQL in PDO. Instead, you just run the count(*) query.
<?php
$sql = "SELECT count(*) FROM `table` WHERE foo = bar";
$result = $con->prepare($sql);
$result->execute();
$number_of_rows = $result->fetchColumn();
Source: Row count with PDO
$stmt = $db->exec( "select count(*) as num from php_blog" );
$results = $stmt->fetch();
$total_results = $results[ 'num' ];
$total_pages = ceil( $total_results / $blog_postnumber );
for($i = 1; $i <= $total_pages; $i++) {
if ($page == $i) {
echo "<span class='current'>$i</span>";
}
else {
echo "$i";
}
}

Categories