DEV Community

Patrik Kiss
Patrik Kiss

Posted on • Edited on

How I solved pagination in PHP.

Hi everyone,

This is my first post here, but I'll try my best to format it properly and explain everything correctly, although I'm really bad at professional speech, I can't really talk like a real programmer sadly, so I'll mostly just use regular words and expressions.

So, I think everyone is familiar with the term pagination.
For quite a while I spent a lot of time searching for the simplest pagination solutions on the internet, since unfortunatelly I didn't have the knowledge to do it by myself.

But there was a huge problem: every solution I've seen was either outdated, or extremely overcomplicated, yet were called "simple", like people were just trying to show off their skills, instead of actually trying to help others. Or another problem was that most of them were not dynamic at all.

One night, my brain just wouldn't stop searching for possible solutions, and suddenly I came up with one, which I coded and tested on paper that night. I believe this code is not complicated at all, it's easy to understand, yet works perfectly. In this example we are separating comments into pages. The following examples use a little bit of Bootstrap and Jquery.

First, here is the final result:

Desktop view
Alt Text

Mobile view

Alt Text

Now let's go through the code, step by step.

1.Counting the comments

Here we just have this function called countAllComment()with simple prepared statement, which returns with the number of comments, in classes/comments.php. Nothing new so far.

function countAllComments(){
    $st=$this->conn->prepare("SELECT COUNT(*) FROM comments");
    $st->execute();
    return $st->fetchColumn();
}

2.Let's define some variables we will need, in index.php

require("classes/comments.php");
$comments=new Comments();
require("classes/pagination.php");
$pb=new PageButtons();

$total = $comments->countAllComments();//overall number of comments
$per_page = 15; //comments to display/page
$limit_start = ($_GET['page']*$per_page)-$per_page;
$all_pages = ceil($total/$per_page);//number of all pages
$page_diff = $all_pages-$_GET['page'];//difference between current page and number of all pages
$base_link = "/comments/";//or any other link
$next_link = $base_link.($_GET['page']+1);//leads to next page
$prev_link = $base_link.($_GET['page']-1);//leads to previous page
$next_next_link = $base_link.($_GET['page']+2);//jumps 2 pages forward
$prev_prev_link = $base_link.($_GET['page']-2);//jumps 2 pages back
$last_link = $base_link.$all_pages;//leads to the last page
$first_link = $base_link."1";//leads to the first page

3.Creating the function which draws the buttons, called pageButton(), using Heredoc, in classes/pagination.php

function pageButtons($link,$page,$button_class,$mobile){
        return <<<HTML
        <a href="{$link}">
            <button type="button" class="btn btn-sm {$button_class} page-buttons">
                <span class="d-none d-lg-block">
                    {$page}<!--page number-->
                </span>
                <span class="d-block d-lg-none font-weight-bold">
                    {$mobile}<!--text to display on mobile view-->
                </span>
            </button>
        </a>
HTML;
    }

4.And now the pagination code itself, also in classes/pagination.php

4.1--First, we have nextButtons() which returns with the buttons that take us forward/to the next pages.

function nextButtons($current_page,$all_pages,$page_diff,$next_link,$next_next_link,$last_link){
        if($all_pages>$current_page){
            if($page_diff>=1){
                echo $this->pageButtons($next_link,$current_page+1,"btn-outline-light",$current_page+1);
            }
            if($page_diff>=2){
                echo $this->pageButtons($next_next_link,$current_page+2,"btn-outline-light",$current_page+2);
            }
            if($page_diff>=1){
                echo $this->pageButtons($next_link,"Next","btn-outline-light","<i class='fas fa-angle-right'></i>");
            }
            if($page_diff>=3){
                echo $this->pageButtons($last_link,"Last","btn-outline-light","<i class='fas fa-angle-double-right'></i>");
            }
        }
    }

Let me try to explain how it works exactly:

page_diff=all_pages-current_page

if($page_diff>=1)/*if the page difference is at least 1,
it means we can jump 1 page forward.
So a button which does so will be displayed.*/


all_pages=10;
$current_page=8--->10-8=2//✔
$current_page=9--->10-9=1//✔
$current_page=10--->10-10=0//✖




if($page_diff>=2)/*If the page difference is at least 2,
it means we can jump 2 pages ahead.
So a button that does so will be displayed too*/


all_pages=10;
$current_page=7--->10-7=3//✔
$current_page=8--->10-8=2//✔
$current_page=9--->10-9=1//✖




if($page_diff>=3)/*If the page difference is at least 3,
that means we can't jump to the last page with any of the buttons from above,
so one that leads there will be displayed as well.*/


all_pages=10;
$current_page=6--->10-6=4//✔
$current_page=7--->10-7=3//✔
$current_page=8--->10-8=2//✖

4.2--You can't tell it just from the picture, but in the center, which show the current page, is actually a select Using that you can freely jump to any page you want.

function pageSelect($all_pages,$current_page,$page_link){
        ?>
        <select class="form-control m-0 p-0 d-inline bg-transparent text-info border-info all-pages">
            <?php
            for ($i=1; $i < $all_pages+1; $i++) { 
                ?>
                <option class="text-dark" <?php
                if($current_page==$i){
                    echo "selected";
                }
                ?> value="<?php
                echo $page_link.$i;
                ?>">
                    <?php
                        echo $i;
                    ?>
                </option>
                <?php
            }
            ?>
        </select>
        <?php
    }

In short: in the value attribute of the options, our current location(comments/)+number of page($i) will be displayed.

For this to actually work, there is this small piece of Jquery code.

$(".all-pages").on("change",function(){
        $(this).find("option").each(function(){
            if($(this).is(":selected")){
                location.href=$(this).attr("value");
            }
        });
    });

4.3--And finally, we have some buttons to go back to a previous page, in function prevButtons()

function prevButtons($current_page,$prev_link,$prev_prev_link,$first_link){
        if($current_page>1){
            if(($current_page+1)-3>1){
                echo $this->pageButtons($first_link,"First","btn-outline-light","<i class='fas fa-angle-double-left'></i>");
            }
            if(($current_page+1)-1>1){
                echo $this->pageButtons($prev_link,"Prev","btn-outline-light","<i class='fas fa-angle-left'></i>");
            }
            if(($current_page+1)-2>1){
                echo $this->pageButtons($prev_prev_link,$current_page-2,"btn-outline-light",$current_page-2);
            }
            if(($current_page+1)-1>1){
                echo $this->pageButtons($prev_link,$current_page-1,"btn-outline-light",$current_page-1);
            }
        }
    }

Now this is interesting, I'll try to explain it with examples:

/*we always add 1 to the current_page, to avoid 0 being the result,
that's how the code will work properly*/

//the formula looks something like this:
if((current_page+1)-pages_to_go_back>1)

/*the outcome/result must always be larger than 1*/

if(($current_page+1)-1>1)//Must be at least on the 2nd page, so that we can go back once.

$current_page=1---->(1+1)-1=1//✖
$current_page=2---->(2+1)-1=2//✔
$current_page=3---->(3+1)-1=3//✔



if(($current_page+1)-2>1)//Must be at least on the 3rd page, so that we can go back twice.

$current_page=2---->(2+1)-2=1//✖
$current_page=3---->(3+1)-2=2//✔
$current_page=4---->(4+1)-2=3//✔



if(($current_page+1)-3>1)/*Here 'pages_to_go_back' is 3,
because we go back at least 3 pages.
That means, we must be at least on the 4th page,
so that we can jump directly to the first page,
since if we are on the 3rd page,
a button which leads to the first page already exists(previous example).*/

$current_page=3---->(3+1)-3=1//✖
$current_page=4---->(4+1)-3=2//✔
$current_page=5---->(5+1)-3=3//✔

5.At last, let's go back to index.php, and add the following 3 lines of code.

echo $pb->prevButtons($_GET['page'],$prev_link,$prev_prev_link,$first_link);
echo $pb->pageSelect($all_pages,$_GET['page'],$base_link);
echo $pb->nextButtons($_GET['page'],$all_pages,$page_diff,$next_link,$next_next_link,$last_link);

And we're done.

I've made a few changes from the original one, so I might have mistyped something.

I really hope I made sense most of the time, and you managed to understand how the code works. I know I couldn't explain everything well, but I tried my best. Let me know what you think about this solution, and the whole post itself.

Top comments (0)