Toidicode.com

Toidicode.com

BASIC TO ADVANCE

Tạo lớp phân trang đơn giản với PHP

Download Source

Nếu như các bạn đã từng sử dụng các framework thì chắc hẳn các bạn cũng đã biết mỗi framework đều có một lớp pagination (phân trang) của riêng nó. Và hôm nay mình sẽ hướng dẫn mọi người xây dựng một lớp phân trang đơn giản để các bạn có thể sử dụng vào trong dự án của bản thân.

1, Thuật toán.

Nhìn chung thì thuật toán phân trang của chúng ta cũng hết sức đơn giản như sau:

  • Đầu tiên chúng ta cần xác định xem có tổng cộng bao nhiêu bản ghi cần phân trang (total).
  • Tiếp đó chúng ta muốn bao nhiêu bản ghi trên một trang (limit).
  • Sau khi có được 2 thông số trên thì chúng ta sẽ cần phải xác định được số lượng trang sẽ được chia ra sẽ được tính bằng: total/limit, nhưng lúc này nó sẽ tồn tại một vài lỗi nếu như phép toán trên là lẻ (chẳng hạn như 152/5) nên chúng ta sẽ cho nó làm tròn lên bằng hàm ceil() trong PHP.
  • Khi muốn xuất ra số trang thì chúng ta sẽ dùng vòng lặp hiển thị ra các trang và link của nó.

Về phần lý thuyết là như thế, giờ chúng ta sẽ cùng đi vào xây dựng code.

2, Xây dựng lớp.

-Và đây là lớp mà chúng ta sẽ xây dựng được. Trong lớp này mình có comment một số đoạn, còn một số đoạn mình sẽ không giải thích mà mình sẽ để cho các bạn tự ôn lại bài cũ luôn.

<?php

/**
 * Pagination basic created by toidicode.com
 *
 * @package Pagination basic
 * @author  ThanhTai - ToiDiCodeTeam
 * @copyright   Copyright (c) 2017, Toidicode Team. (http://toidicode.com/)
 * @link    https://toidicode.com
 * @since   Version 1.0.0
 * @filesource
 */
class Pagination
{
    /**
     * Biến config chứa tất cả các cấu hình
     *
     * @var array
     */
    private $config = [
        'total' => 0, // tổng số mẩu tin
        'limit' => 0, // số mẩu tin trên một trang
        'full' => true, // true nếu hiện full số page, flase nếu không muốn hiện false
        'querystring' => 'page' // GET id nhận page
    ];

    /**
     * khởi tạo
     *
     * @param array $config
     */
    public function __construct($config = [])
    {
        // kiểm tra xem trong config có limit, total đủ điều kiện không
        if (isset($config['limit']) && $config['limit'] < 0 || isset($config['total']) && $config['total'] < 0) {
            // nếu không thì dừng chương trình và hiển thị thông báo.
            die('limit và total không được nhỏ hơn 0');
        }
        // Kiểm tra xem config có querystring không
        if (!isset($config['querystring'])) {
            //nếu không để mặc định là page
            $config['querystring'] = 'page';
        }
        $this->config = $config;
    }

    /**
     * Lấy ra tổng số trang
     *
     * @return int
     */
    private function gettotalPage()
    {
        return ceil($this->config['total'] / $this->config['limit']);
    }

    /**
     * Lấy ra trang hiện tại
     *
     * @return int
     */
    private function getCurrentPage()
    {
        // kiểm tra tồn tại GET querystring và có >=1 không
        if (isset($_GET[$this->config['querystring']]) && (int)$_GET[$this->config['querystring']] >= 1) {
            // Nếu có kiểm tra tiếp xem nó có lớn hơn tổn số trang không.
            if ((int)$_GET[$this->config['querystring']] > $this->gettotalPage()) {
                // nếu lớn hơn thì trả về tổng số page
                return (int)$this->gettotalPage();
            } else {
                // còn không thì trả về số trang
                return (int)$_GET[$this->config['querystring']];
            }

        } else {
            // nếu không có querystring thì nhận mặc định là 1
            return 1;
        }
    }

    /**
     * lấy ra trang phía trước
     *
     * @return string
     */
    private function getPrePage()
    {
        // nếu trang hiện tại bằng 1 thì trả về null
        if ($this->getCurrentPage() === 1) {
            return;
        } else {
            // còn không thì trả về html code
            return '<li><a href="' . $_SERVER['PHP_SELF'] . '?' . $this->config['querystring'] . '=' . ($this->getCurrentPage() - 1) . '" >Pre</a></li>';
        }
    }

    /**
     * Lấy ra trang phía sau
     *
     * @return string
     */
    private function getNextPage()
    {
        // nếu trang hiện tại lơn hơn = totalpage thì trả về rỗng
        if ($this->getCurrentPage() >= $this->gettotalPage()) {
            return;
        } else {
            // còn không thì trả về HTML code
            return '<li><a href="' . $_SERVER['PHP_SELF'] . '?' . $this->config['querystring'] . '=' . ($this->getCurrentPage() + 1) . '" >Next</a></li>';
        }
    }

    /**
     * Hiển thị html code của page
     *
     * @return string
     */
    public function getPagination()
    {
        // tạo biến data rỗng
        $data = '';
        // kiểm tra xem người dùng có cần full page không.
        if (isset($this->config['full']) && $this->config['full'] === false) {
            // nếu không thì
            $data .= ($this->getCurrentPage() - 3) > 1 ? '<li>...</li>' : '';

            for ($i = ($this->getCurrentPage() - 3) > 0 ? ($this->getCurrentPage() - 3) : 1; $i <= (($this->getCurrentPage() + 3) > $this->gettotalPage() ? $this->gettotalPage() : ($this->getCurrentPage() + 3)); $i++) {
                if ($i === $this->getCurrentPage()) {
                    $data .= '<li class="active" ><a href="#" >' . $i . '</a></li>';
                } else {
                    $data .= '<li><a href="' . $_SERVER['PHP_SELF'] . '?' . $this->config['querystring'] . '=' . $i . '" >' . $i . '</a></li>';
                }
            }

            $data .= ($this->getCurrentPage() + 3) < $this->gettotalPage() ? '<li>...</li>' : '';
        } else {
            // nếu có thì
            for ($i = 1; $i <= $this->gettotalPage(); $i++) {
                if ($i === $this->getCurrentPage()) {
                    $data .= '<li class="active" ><a href="#" >' . $i . '</a></li>';
                } else {
                    $data .= '<li><a href="' . $_SERVER['PHP_SELF'] . '?' . $this->config['querystring'] . '=' . $i . '" >' . $i . '</a></li>';
                }
            }
        }

        return '<ul>' . $this->getPrePage() . $data . $this->getNextPage() . '</ul>';
    }
}

3, Hướng dẫn sử dụng.

-Để sử dụng được lớp trên thì các bạn chỉ cần khởi tạo với các thông số như sau:

//Khởi tạo class
$config = [
    'total' => 150, 
    'limit' => 5,
    'full' => false, //bỏ qua nếu không muốn hiển thị full page
    'querystring' => 'trang' //bỏ qua nếu GET của bạn là page
    ];
$page = new Pagination($config);
//hiển thị code
echo $page->getPagination();

VD: Mình sẽ cấu hình lớp với 160 bản ghi và mỗi trang sẽ hiển thị 7 bản ghi. đồng thời sẽ hiển thị full page và CSS lại cho đẹp xíu.

<?php require_once 'Pagination.php'; ?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>page</title>
</head>
<style type="text/css" media="screen">
    ul{
        list-style: none;
    }
    ul:after{
        clear: both;
    }
    ul li{
        background: #dddddd;
        width: 35px;
        height: 30px;
        line-height: 30px;
        float: left;
        text-align: center;
        margin-right: 1px;
    }
    a{
        text-decoration: none;
    }
    ul li.active{
        color:white;
        background: blue;
    }
    .active a{
        color:white;
    }
    
</style>
<body>
    <?php 
    $config = [
        'total' => 167, 
        'limit' => 7,
        'full' => true,
        'querystring' => 'trang'
        ];
    $page = new Pagination($config);
    echo $page->getPagination();
    ?>
</body>
</html>

Và kế quả sẽ như sau:

kết quả

VD: Vẫn với ví dụ trên nhưng mình không để full page nữa.

<?php require_once 'Pagination.php'; ?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>page</title>
</head>
<style type="text/css" media="screen">
    ul {
        list-style: none;
    }

    ul:after {
        clear: both;
    }

    ul li {
        background: #dddddd;
        width: 35px;
        height: 30px;
        line-height: 30px;
        float: left;
        text-align: center;
        margin-right: 1px;
    }

    a {
        text-decoration: none;
    }

    ul li.active {
        color: white;
        background: blue;
    }

    .active a {
        color: white;
    }

</style>
<body>
<?php
    $config = [
        'total' => 167,
        'limit' => 7,
        'full' => false,
        'querystring' => 'trang'
    ];
    
    $page = new Pagination($config);
    
    echo $page->getPagination();
?>
</body>
</html>

Và đây là kết quả:

kết quả

4, Lời kết.

Như vậy mình đã hướng dẫn mọi người xây dựng xong một lớp phân trang đơn giản với PHP rồi, các bạn hoàn toàn có thể phát triển thêm sao cho nó phù hợp với dự án của các bạn nhất.

Chúc các bạn thành công.

Đăng ký nhận tin.

Chúng tôi chỉ gửi tối đa 2 lần trên 1 tháng. Tuyên bố không spam mail!

Vũ Thanh Tài

About author
The best way to learn is to share
Xem tất cả bài đăng

3 Comments

Em chào anh Tài,

Em cảm ơn anh về bài viết này, hiện tại em có một vấn đề mà em không biết cách giải quyết.

Có cách nào xác định phân trang hiện tại là bao nhiêu không ạ, em cần nó để em làm điều kiện hiển thị trên các phân trang.

Em sử dụng WordPress.

Em mong nhận được sự hướng dẫn và giúp đỡ của anh.

Em cảm ơn anh.

Trân trọng.

PHONG

6 năm trước

Chào bạn!

Bạn có thể sử dụng $paged của wordpress nhé!
 

global $paged;
echo $paged;

 

Vũ Thanh Tài

6 năm trước

Cám ơn ad bài viết hay 

ELY SPA

5 năm trước

Bình luận

Captcha