1
\$\begingroup\$

I went through lots of tutorial, and almost all of them were quite long, so I came up with my own code:

  $page = $_GET['page'];
  $pg_count = $page-1;

  if ($page == 1) {

    $start = 0;

  } else {

    $start = $pg_count*15;

  }

  $limit = $page*15;

  $query = 'SELECT * FROM table LIMIT '.$start.', '.$limit.'';

  foreach($db->query($query) as $row) {

    //outputs

  }

  $stmt = $db->query('SELECT * FROM table'); 
  $row_count = $stmt->rowCount(); 

  $count = ceil($row_count/15);

  for ($i=1; $i<=$count; $i++) {

  echo '<a href="?page='.$i.'">'.$i.'</a>';

  }

Here i'm displaying 15 results per page.

This small piece of code seems to do the job (new to pdo, sorry if the method of including parameter is wrong).

So basically my question is, is their a much better way to do this?

EDIT:

I couldn't figure out a good approach so I came up with this horrible code:

if ($page != 1) {


  if ($page > 5) {

    $sdot = '....';

  } else {

    $sdot = '';

  }

  echo '<a href="?page=1" class="page" >First</a>'.$sdot ;

}


  if ($page < 5) {

    for ($i=1; $i<=5; $i++) {

      echo '<a href="?page='.$i.'">'.$i.'</a>';

    }

  } elseif (($page > 5) && ($page < ($count-5))) {

    for ($i=($page-2); $i<=($page+2); $i++) {

      echo '<a href="?page='.$i.'">'.$i.'</a>';

    }

  } elseif (($page > ($count-7)) && ($page < ($count-2))) {

    for ($i=($page-2); $i<=($page+2); $i++) {

      echo '<a href="?page='.$i.'">'.$i.'</a>';

    }

  } else {

    for ($i=($page-2); $i<=$count; $i++) {

      echo '<a href="?page='.$i.'">'.$i.'</a>';

    }

  }


if ($page != $count) {

  if ($page < ($count-2)) {

    $edot = '....';

  } else {

    $edot = '';

  }

  echo $edot.'<a href="?page='.$count.'" class="page">Last</a>';

}
\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

This is a pagination code that I used in one of my old applications. You should change the mysql_ functions to pdo/mysqli here. This is based on a simple table with id, name fields. Change the queries according to your logic.

if (isset($_GET['page'])){
    $page = $_GET['page'];
}

// get total no. of rows from the table
$page_query = "SELECT COUNT(*) as C FROM table";
$RSp = MYSQL_QUERY($page_query) or die(mysql_error());
$rowp = mysql_fetch_array($RSp, MYSQL_ASSOC);

$num_rows = $rowp['C'];
$rows_per_page = 100;      // you can change this to what you want
$first = 1;
$last = ceil ($num_rows/$rows_per_page);

if (($page == '') || ($page < $first) || ($page > $last)){
    $page = 1;
}

$lower_limit = (($page-1)*$rows_per_page);
$count = 0;

// main query to generate page content based on 
// pagination logic
$query = "Select * from table order by name ";
$query.= "LIMIT ".$lower_limit.", ".$rows_per_page;

// generate page content here
// pagination code at the bottom of the page goes here

<!--This is the main pagination HTML Code-->
<ul id="pagination-clean">
<?php
 if ($page == 1){
?>
     <li class="previous-off">Previous</li>
<?php
}
else {
?>
    <li class="previous"><a href="?page=<?php echo ($page-1); ?>">Previous</a></li>
<?php
} // end else
for ($i = 1; $i<=$last;$i++){
    // This is the query statement for displaying the name of 
    // first and last entry of the page 
    // on paginated links
    $lower = (($i-1) * $rows_per_page);
    $upper = (($i*$rows_per_page) - 1);

    $query_low = "SELECT Name, SUBSTRING(Name, 1, 2) AS `Name_S` FROM ";
    $query_low.=  "table ORDER BY Name ASC LIMIT ".$lower.", 1";
    $RSl = MYSQL_QUERY($query_low) or die(mysql_error());
    $row_low = mysql_fetch_array($RSl, MYSQL_ASSOC);
    $lname = $row_low['Name'];
    $lname_s = $row_low['Name_S'];

    $query_up = "SELECT Name, SUBSTRING(Name, 1, 2) AS `Name_S` FROM ";
    $query_up.= "table ORDER BY Name ASC LIMIT ".$upper.", 1";
    $RSu = MYSQL_QUERY($query_up) or die(mysql_error());
    $row_up = mysql_fetch_array($RSu, MYSQL_ASSOC);
    if (!$row_up){
        $query_up = "SELECT Name, SUBSTRING(Name, 1, 2) AS `Name_S` FROM ";
        $query_up.= "table ORDER BY Name ASC LIMIT ".($num_rows-1).", 1";
        $RSu = MYSQL_QUERY($query_up) or die(mysql_error());
        $row_up = mysql_fetch_array($RSu, MYSQL_ASSOC);        
    }
    $uname = $row_up['Name'];
    $uname_s = $row_up['Name_S'];

    if ($i == $page){
?>
        <li class="previous-off"><?php echo $i ." (".$lname_s." - ".$uname_s.")"; ?></li>
<?php
  }
   else {
 ?>
       <li><a href="?page=<?php echo $i; ?>" ><?php echo $i ." (".$lname_s." - ".$uname_s.")"; ?></a></li>
<?php
    }
  } // end for loop

  if ($page == $last){
?>
        <li class="next-off">Next</li>
<?php
}
else {
?>    
    <li class="next"><a href="?page=<?PHP echo ($page+1)?>">Next</a></li>
<?php
 }
?>
</ul>
  <!-- end pagination code here -->    

This is the CSS:

#pagination-clean li          { border:0; margin:0; padding:0; font-size:11px;       list-style:none; /* savers */ float:left; }
/* savers #pagination-clean li,*/
#pagination-clean a           { border-right:solid 1px #DEDEDE; margin-right:2px; }
#pagination-clean .previous-off,
#pagination-clean .next-off   { color:#888888; display:block; float:left; font-weight:bold; padding:3px 4px; }  
#pagination-clean .next a,
#pagination-clean previous a  { border:none; font-weight:bold; }  
#pagination-clean .active     { color:#000000; font-weight:bold; display:block; float:left; padding:4px 6px; /* savers */ border-right:solid 1px #DEDEDE; }
#pagination-clean a:link,
#pagination-clean a:visited   { color:#0e509e; display:block; float:left; padding:3px 6px; text-decoration:underline; }
#pagination-clean a:hover     { text-decoration:none; 

This is a screenshot of what the page looks like:

https://i.stack.imgur.com/3px7n.jpg

(In addition to the page no., it also displays the first 2 characters of the name field)

See if this helps. Let me know if you have any questions.

\$\endgroup\$
16
  • \$\begingroup\$ Yes it is good, but can you point out improvements in my code, as it also works, and I can add css later on and I have isset check on $_GET['page'].. \$\endgroup\$ Jul 22, 2013 at 19:51
  • \$\begingroup\$ since your code works fine, the only improvement that I can think of would be making rows per page parameter dynamic so that you can easily switch from 15 rows per page to any no. of rows you want. Other improvement could be this part: if (($page == '') || ($page < $first) || ($page > $last)){ $page = 1; } \$\endgroup\$ Jul 22, 2013 at 19:54
  • \$\begingroup\$ what you might also want to do is test your case for different page values and see if it handles all the cases correctly. Other than that it looks good. \$\endgroup\$ Jul 22, 2013 at 19:55
  • \$\begingroup\$ Yes, i tested it for 50 values, and yes thanks for next and last thing, and how can I do something like First 1 2...8 9(current page) 10...81 82 last \$\endgroup\$ Jul 22, 2013 at 20:08
  • \$\begingroup\$ can you clarify that a bit more ? \$\endgroup\$ Jul 22, 2013 at 21:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.