Phân trang trong CodeIgniter: Hướng dẫn Hoàn chỉnh

Discussion in 'PHP, Java , JS ....' started by admin, Feb 21, 2018.

  1. admin

    admin Administrator Staff Member

    Lợi ích của việc sử dụng framework full stack cho ứng dụng web đó là bạn không phải lo lắng về các tác vụ thông thường như xử lý đầu vào, kiểm tra form và những thứ tương tự, vì framework đã cung cấp các wrapper cho các tính năng đó. Do đó, nó cho phép bạn tập trung vào logic của ứng dụng thay vì làm đi làm lại những công việc đó.

    Hôm nay, chúng ta sẽ khám phá một thư viện quan trọng trong framework CodeIgniter - thư viện phân trang.

    Để tôi khái quát các chủ đề mà chúng ta sẽ thảo luận trong bài viết này:

    1. Minh hoạ cơ bản về chức năng phân trang
    2. Khám phá các tùy chọn tùy biến
    3. Cấu hình phân trang
    4. Minh hoạ cơ bản về chức năng phân trang
    Trong phần này, chúng ta sẽ đi tìm hiểu một ví dụ minh hoạ việc sử dụng phân trang trong CodeIgniter. Đó là cách tốt nhất để hiểu mọi thứ hoạt động như thế nào.

    Trong ví dụ của chúng ta, chúng ta sẽ xây dựng một danh sách người dùng khá đơn giản, trong đó chúng ta sẽ truy vấn các bản ghi từ bảng users trong CSDL MySQL. Để chạy thành công ví dụ này, hãy đảm bảo rằng bạn có các trường uid và uname trong bảng users của bạn.

    Với thiết lập đó, chúng ta đã sẵn sàng để thực hiện.

    Hãy tiếp tục và tạo một tập tin controller controllers/Paging.php với các nội dung sau.

    PHP:
    <?php
    defined('BASEPATH') OR exit('No direct script access allowed');

    class Paging extends CI_Controller {
    public function __construct()
    {
    parent::__construct();

    // load Pagination library
    $this->load->library('pagination');

    // load URL helper
    $this->load->helper('url');
    }

    public function index()
    {
    // load db and model
    $this->load->database();
    $this->load->model('Users');

    // init params
    $params = array();
    $limit_per_page = 1;
    $start_index = ($this->uri->segment(3)) ? $this->uri->segment(3) : 0;
    $total_records = $this->Users->get_total();

    if ($total_records > 0)
    {
    // get current page records
    $params["results"] = $this->Users->get_current_page_records($limit_per_page, $start_index);

    $config['base_url'] = base_url() . 'paging/index';
    $config['total_rows'] = $total_records;
    $config['per_page'] = $limit_per_page;
    $config["uri_segment"] = 3;

    $this->pagination->initialize($config);

    // build paging links
    $params["links"] = $this->pagination->create_links();
    }

    $this->load->view('user_listing', $params);
    }

    public function custom()
    {
    // load db and model
    $this->load->database();
    $this->load->model('Users');

    // init params
    $params = array();
    $limit_per_page = 2;
    $page = ($this->uri->segment(3)) ? ($this->uri->segment(3) - 1) : 0;
    $total_records = $this->Users->get_total();

    if ($total_records > 0)
    {
    // get current page records
    $params["results"] = $this->Users->get_current_page_records($limit_per_page, $page*$limit_per_page);

    $config['base_url'] = base_url() . 'paging/custom';
    $config['total_rows'] = $total_records;
    $config['per_page'] = $limit_per_page;
    $config["uri_segment"] = 3;

    // custom paging configuration
    $config['num_links'] = 2;
    $config['use_page_numbers'] = TRUE;
    $config['reuse_query_string'] = TRUE;

    $config['full_tag_open'] = '<div class="pagination">';
    $config['full_tag_close'] = '</div>';

    $config['first_link'] = 'First Page';
    $config['first_tag_open'] = '<span class="firstlink">';
    $config['first_tag_close'] = '</span>';

    $config['last_link'] = 'Last Page';
    $config['last_tag_open'] = '<span class="lastlink">';
    $config['last_tag_close'] = '</span>';

    $config['next_link'] = 'Next Page';
    $config['next_tag_open'] = '<span class="nextlink">';
    $config['next_tag_close'] = '</span>';

    $config['prev_link'] = 'Prev Page';
    $config['prev_tag_open'] = '<span class="prevlink">';
    $config['prev_tag_close'] = '</span>';

    $config['cur_tag_open'] = '<span class="curlink">';
    $config['cur_tag_close'] = '</span>';

    $config['num_tag_open'] = '<span class="numlink">';
    $config['num_tag_close'] = '</span>';

    $this->pagination->initialize($config);

    // build paging links
    $params["links"] = $this->pagination->create_links();
    }

    $this->load->view('user_listing', $params);
    }
    }
    Tiếp theo, chúng ta sẽ cần một tập tin model models/Users.php để lấy các bản ghi từ bảng users.

    PHP:
    <?php
    // models/Users.php
    defined('BASEPATH') OR exit('No direct script access allowed');

    class Users extends CI_Model
    {
    function __construct()
    {
    parent::__construct();
    }

    public function get_current_page_records($limit, $start)
    {
    $this->db->limit($limit, $start);
    $query = $this->db->get("users");

    if ($query->num_rows() > 0)
    {
    foreach ($query->result() as $row)
    {
    $data[] = $row;
    }

    return $data;
    }

    return false;
    }

    public function get_total()
    {
    return $this->db->count_all("users");
    }
    }
    Cuối cùng, hãy tạo một tập tin view views/user_listing.php để hiển thị danh sách người dùng.
    PHP:
    <!-- views/user_listing.php -->
    <html>
    <head>
    <title>Paging Example-User Listing</title>
    </head>

    <body>
    <div class="container">
    <h1 id='form_head'>User Listing</h1>

    <?php if (isset($results)) { ?>
    <table border="1" cellpadding="0" cellspacing="0">
    <tr>
    <th>ID</th>
    <th>NAME</th>
    </tr>

    <?php foreach ($results as $data) { ?>
    <tr>
    <td><?php echo $data->uid ?></td>
    <td><?php echo $data->uname ?></td>
    </tr>
    <?php } ?>
    </table>
    <?php } else { ?>
    <div>No user(s) found.</div>
    <?php } ?>

    <?php if (isset($links)) { ?>
    <?php echo $links ?>
    <?php } ?>
    </div>
    </body>
    </html>
    Bây giờ, hãy truy cập vào trang tùy biến của chúng ta tại http://your-code-igniter-site/paging/index và bạn sẽ thấy danh sách người dùng được phân trang! Như vậy là chúng ta thực hiện xong! Đừng lo lắng, tôi sẽ không bỏ mặc bạn sớm như vậy đâu, vì chúng ta sẽ bắt đầu phân tích từng phần của đoạn code ngay bây giờ.

    Chúng ta sẽ bắt đầu với tập tin model models/Users.php vì đó là những thứ sẽ được gọi từ các phương thức controller của chúng ta. Có hai phương thức quan trọng, get_current_page_records và get_total, các cài đặt model đó của chúng ta nhằm xây dựng các liên kết phân trang.

    Hãy tìm hiểu phương thức get_total. Nó được sử dụng để đếm số bản ghi trong bảng users.

    PHP:
    public function get_total()
    {
    return $this->db->count_all("users");
    }
    Tiếp theo, phương thức get_current_page_records.

    PHP:
    public function get_current_page_records($limit, $start)
    {
    $this->db->limit($limit, $start);
    $query = $this->db->get("users");

    if ($query->num_rows() > 0)
    {
    foreach ($query->result() as $row)
    {
    $data[] = $row;
    }

    return $data;
    }

    return false;
    }
    Có hai đối số quan trọng mà bạn nên lưu ý trong phương thức get_current_page_records. Đối số đầu tiên, $limit, được sử dụng để chỉ định số bản ghi sẽ được trả về trong quá trình thực thi truy vấn. Và đối số thứ hai, $start, đóng vai trò như là chỉ số bắt đầu của bản ghi.

    Như bạn thấy đấy, với các giá trị của $start và $limit chúng ta có thể lấy về các bản ghi theo trang. Đó là bản chất của phân trang, và như vậy chúng ta đã cài đặt phương thức quan trọng nhất của bài viết này!

    Như vậy, đó là model của chúng ta - đơn giản!

    Tiếp tục, chúng ta hãy tập trung vào tập tin controller. Hãy lấy code của phương thức constructor.

    PHP:
    public function __construct()
    {
    parent::__construct();

    // load Pagination library
    $this->load->library('pagination');

    // load URL helper
    $this->load->helper('url');
    }
    Để sử dụng phân trang trong CodeIgniter, điều đầu tiên bạn cần làm là nạp thư viện phân trang (pagination). Và chúng ta có thể làm điều đó bằng cách sử dụng
    PHP:
    $this->load->library('pagination').
    Đồng thời chúng ta nạp URL helper để chúng ta có thể sử dụng các hàm trợ giúp toàn cục được cung cấp bởi helper đó.

    Bây giờ, chúng ta đã sẵn sàng để đi sâu vào trái tim của controller - phương thức index.
    PHP:
    public function index()
    {
    // load db and model
    $this->load->database();
    $this->load->model('Users');

    // init params
    $params = array();
    $limit_per_page = 1;
    $start_index = ($this->uri->segment(3)) ? $this->uri->segment(3) : 0;
    $total_records = $this->Users->get_total();

    if ($total_records > 0)
    {
    // get current page records
    $params["results"] = $this->Users->get_current_page_records($limit_per_page, $start_index);

    $config['base_url'] = base_url() . 'paging/index';
    $config['total_rows'] = $total_records;
    $config['per_page'] = $limit_per_page;
    $config["uri_segment"] = 3;

    $this->pagination->initialize($config);

    // build paging links
    $params["links"] = $this->pagination->create_links();
    }

    $this->load->view('user_listing', $params);
    }
    Để bắt đầu, chúng ta đảm bảo rằng cơ sở dữ liệu được nạp đúng cách. Sau đó, chúng ta nạp model Users để chúng ta có thể sử dụng các phương thức của model đó.
    PHP:
    $this->load->database();
    $this->load->model('Users');
    Tiếp theo, chúng ta khởi tạo một vài biến quan trọng.
    PHP:

    // init params
    $params = array();
    $limit_per_page = 1;
    $start_index = ($this->uri->segment(3)) ? $this->uri->segment(3) : 0;
    $total_records = $this->Users->get_total();
    Biến $limit_per_page xác định giới hạn trên mỗi trang. Tất nhiên, bạn có thể thiết lập nó tuỳ ý bạn; nó được thiết lập thành 1 tại thời điểm này nhằm mục đích minh hoạ.

    Biến $start_index giữ chỉ số bắt đầu của bản ghi trong MySQL. Khi CodeIgniter xây dựng các liên kết phân trang, mặc định nó sẽ nối thêm chỉ mục bắt đầu của trang như là phân đoạn thứ ba trong URL. Bạn có thể thay đổi hành vi mặc định này, nhưng đó là điều mà chúng ta sẽ để dành cho phần cuối cùng của bài viết này, nơi chúng ta sẽ thảo luận các tuỳ chọn tùy biến.

    Cuối cùng, chúng ta gọi phương thức get_total của model Users để lấy tổng số bản ghi của bảng users và nó được gán cho biến $total_records.

    Tiếp theo, chúng ta lấy các bản ghi của trang hiện tại bằng phương thức get_current_page_records.
    PHP:
    // get current page records
    $params["results"] = $this->Users->get_current_page_records($limit_per_page, $start_index);
    Trước khi chúng ta có thể thật sự xây dựng các liên kết phân trang, chúng ta cần phải khởi tạo cấu hình phân trang tối thiểu bằng phương thức initialize của thư viện phân trang.
    PHP:
    $config['base_url'] = base_url() . 'paging/index';
    $config['total_rows'] = $total_records;
    $config['per_page'] = $limit_per_page;
    $config["uri_segment"] = 3;

    $this->pagination->initialize($config);
    Và đó là bộ tham số tối thiểu để xây dựng các liên kết phân trang.

    base_url: URL sẽ được sử dụng khi xây dựng các liên kết phân trang
    total_rows: Tổng số bản ghi
    per_page: Số bản ghi trên mỗi trang
    Cuối cùng, chúng ta sử dụng phương thức create_links để xây dựng các liên kết phân trang.
    PHP:
    // build paging links
    $params["links"] = $this->pagination->create_links();
    Phần còn lại chỉ mang tính hình thức là gọi view user_listing và kết xuất ra! Truy cập URL http://your-code-igniter-site/paging/index để xem danh sách người dùng cùng với các liên kết phân trang.

    Như vậy, đó là một ví dụ phân trang vô cùng đơn giản nhưng hữu ích mà bạn có thể mở rộng để phù hợp với các yêu cầu của bạn.

    Trong phần tiếp theo, chúng ta sẽ khám phá cách bạn có thể tùy biến phân trang mặc định liên quan đến giao diện và chức năng.

    Khám phá các Tùy chọn Tuỳ biến
    Trong phần này, chúng ta sẽ khám phá các tùy chọn có sẵn mà bạn có thể sử dụng nếu bạn muốn tùy biến các liên kết phân trang mặc định.

    Phân đoạn URL
    Mặc dù thư viện phân trang của CodeIgniter tự động nhận biết tham số liên quan đến phân trang từ URL, nhưng bạn có thể định nghĩa một giá trị tùy biến nếu bạn có mẫu URL khác.

    PHP:
    $config["uri_segment"] = 4;
    Số của Liên kết
    Tùy chọn num_links cho phép bạn định nghĩa con số liên kết chữ số sẽ được hiển thị trước và sau số trang hiện tại trong liên kết phân trang.

    PHP:
    $config['num_links'] = 2;
    Số trang đóng vai trò là Phân đoạn URI
    Khi bạn truy cập vào phân đoạn URI phân trang, mặc định nó là một chỉ mục bắt đầu. Ví dụ, nếu bạn có mười bản ghi trên mỗi trang, thì phân đoạn URI phân trang là 20 cho trang thứ ba. Thay vào đó, nếu bạn muốn hiển thị số trang thực tế trong các liên kết phân trang, bạn có thể thiết lập use_page_numbers thành TRUE.

    PHP:
    $config['use_page_numbers'] = TRUE;
    Tất nhiên, bạn cần phải đảm bảo rằng bạn tính toán chỉ số bắt đầu sao cho thích hợp dựa trên số trang mà bạn lấy ra từ URL.

    Giữ nguyên Chuỗi Truy vấn
    Thường thì, bạn sẽ gặp tình huống nơi mà bạn muốn giữ nguyên các tham số của chuỗi truy vấn không liên quan đến phân trang. Bạn có thể sử dụng tùy chọn reuse_query_string để kích hoạt tính năng đó.

    PHP:
    $config['reuse_query_string'] = TRUE;
    Đây là một vài tuỳ chọn mà bạn có thể sử dụng để thay đổi chức năng phân trang mặc định. Tiếp theo, chúng ta sẽ xem xét một vài tùy chọn khác cho phép bạn thay đổi cái cách các liên kết phân trang được hiển thị.

    Thẻ Wrapper
    Nếu bạn muốn bọc code phân trang bằng bất kỳ thẻ HTML nào khác thì bạn có thể thực hiện bằng cách sử dụng các tùy chọn full_tag_open và full_tag_close.

    PHP:
    $config['full_tag_open'] = '<div class="pagination">';
    $config['full_tag_close'] = '</div>';
    Nó có thể thật sự hữu ích nếu bạn muốn áp dụng phong cách tùy biến cho các liên kết phân trang.

    Trang đầu, Trang cuối, Tiếp theo, và Trước đó
    Nếu bạn muốn thay đổi phần văn bản đại diện cho các liên kết trang đầu, trang cuối, tiếp theo và trước đó, thì bạn cũng có thể làm điều đó.

    PHP:
    $config['first_link'] = 'First Page';
    $config['last_link'] = 'Last Page';
    $config['next_link'] = 'Next Page';
    $config['prev_link'] = 'Prev Page';
    Ngoài ra, nếu bạn muốn bọc các liên kết riêng lẻ đó đó bằng bất kỳ thẻ HTML nào, bạn có thể thực hiện theo cách tương tự như chúng ta đã làm để bọc toàn bộ code phân trang.

    PHP:
    $config['first_tag_open'] = '<span class="firstlink">';
    $config['first_tag_close'] = '</span>';
     
    $config['last_tag_open'] = '<span class="lastlink">';
    $config['last_tag_close'] = '</span>';
     
    $config['next_tag_open'] = '<span class="nextlink">';
    $config['next_tag_close'] = '</span>';
     
    $config['prev_tag_open'] = '<span class="prevlink">';
    $config['prev_tag_close'] = '</span>';
    Liên kết hiện tại và liên kết số
    Đôi khi, bạn muốn trang trí liên kết hiện tại khác những liên kết còn lại. Bạn có thể làm điều đó bằng cách áp dụng các thẻ wrapper như dưới đây.

    PHP:
    $config['cur_tag_open'] = '<span class="curlink">';
    $config['cur_tag_close'] = '</span>';
    Tương tự, nếu bạn muốn bọc các liên kết số bằng một cái gì đó:

    PHP:
    $config['num_tag_open'] = '<span class="numlink">';
    $config['num_tag_close'] = '</span>';
    Và điều đó đã kết thúc câu chuyện về tuỳ biến. Trên thực tế, bạn có thể xem ví dụ về tuỳ biến tại trang [URL]http://your-code-igniter/site/custom[/URL] đã được bao gồm trong tập tin controller của chúng ta!

    Cấu hình Phân trang
    Bây giờ bạn đã tìm hiểu về cấu hình cần thiết để thiết lập một phân trang khá hoàn chỉnh với bất kỳ model nào. Và phần lớn, bạn muốn giữ cho nó trông giống nhau trên toàn bộ trang web. Bạn sẽ làm gì để đạt được điều đó? Nếu không biết, bạn có thể sao chép code cấu hình và dán nó vào mỗi hành động yêu cầu cấu hình phân trang.

    Thực tế, có một cách tốt hơn để bạn có thể xử lý tình huống này. Bạn có thể tạo tập tin cấu hình phân trang tại application/config/pagination.php và sử dụng biến $config để định nghĩa các cài đặt của bạn.

    PHP:
    <?php
    $config
    ['per_page'] = 10;
    $config["uri_segment"] = 3;
     
    $config['full_tag_open'] = '<div class="pagination">';
    $config['full_tag_close'] = '</div>';
        
    $config['first_link'] = 'First Page';
    $config['first_tag_open'] = '<span class="firstlink">';
    $config['first_tag_close'] = '</span>';
        
    $config['last_link'] = 'Last Page';
    $config['last_tag_open'] = '<span class="lastlink">';
    $config['last_tag_close'] = '</span>';
        
    $config['next_link'] = 'Next Page';
    $config['next_tag_open'] = '<span class="nextlink">';
    $config['next_tag_close'] = '</span>';
     
    $config['prev_link'] = 'Prev Page';
    $config['prev_tag_open'] = '<span class="prevlink">';
    $config['prev_tag_close'] = '</span>';
     
    $config['cur_tag_open'] = '<span class="curlink">';
    $config['cur_tag_close'] = '</span>';
     
    $config['num_tag_open'] = '<span class="numlink">';
    $config['num_tag_close'] = '</span>';
    Dựa vào đóphương thức hành động index được sửa đổi sẽ như sau:
    PHP:
    public function 
    index()
    {
        
    // load db and model
        
    $this->load->database();
        
    $this->load->model('Users');
     
        
    // init params
        
    $params = array();
        
    $start_index = ($this->uri->segment(3)) ? $this->uri->segment(3) : 0;
        
    $total_records $this->Users->get_total();
        
        
    // load config file
        
    $this->config->load('pagination'TRUE);
        
    $settings $this->config->item('pagination');
        
    $settings['total_rows'] = $this->Users->get_total();
        
    $settings['base_url'] = base_url() . 'paging/config';
     
        if (
    $total_records 0)
        {
            
    // get current page records
            
    $params["results"] = $this->Users->get_current_page_records($settings['per_page'], $start_index);
            
            
    // use the settings to initialize the library
            
    $this->pagination->initialize($settings);
            
            
    // build paging links
            
    $params["links"] = $this->pagination->create_links();
        }
        
        
    $this->load->view('user_listing'$params);
    }
    Tất nhiêncác biến total_rows và base_url sẽ thay đổi ứng với các hành động khác nhauvì vậy bạn cần thiết lập chúng một cách rõ ràng trong mỗi hành động.

    Để thực hiện điều đóbạn cần phải nạp cấu hình phân trang lúc bắt đầu.

    PHP:
    $this->config->load('pagination'TRUE);
    $settings $this->config->item('pagination');
    Tiếp theobạn có thể thay thế các cài đặt cụ thể của hành động.
    PHP:
    $settings['total_rows'] = $this->Users->get_total();
    $settings['base_url'] = base_url() . 'paging/config';
    Và bạn hoàn thành nó!

    [
    EMAIL]mikey.harry@aol.com[/EMAIL]
    My PGP key: [URL]https://goo.gl/triziq[/URL]
     

Share This Page