Logo
  • 歡迎加入 CodeIgniter4
    • 歡迎加入 CodeIgniter4
    • 系統需求
    • 貢獻
    • PSR 規範
  • 安裝指引
    • Composer 安裝
    • 手動安裝
    • 執行你的應用程式
    • 從舊版升級
    • 故障排除
    • CodeIgniter 儲存庫
  • 建構第一個應用程式
    • 靜態頁面
    • 新聞頁面
    • 建立新聞
    • 結論
  • CodeIgniter4 概觀
    • 應用程式結構
    • 模型、視圖與控制器
    • 自動載入檔案
    • 服務(services)
    • 工廠模式
    • 處裡 HTTP 請求
    • 安全指南
  • 一般主題
    • 組態設定檔案
    • CodeIgniter URLs
    • 輔助函數
    • 全域函數與常數
    • 記錄日誌資訊
    • 錯誤處理
    • 網頁快取
    • AJAX 請求
    • 程式碼模組
    • 管理你的應用程式
    • 處理多種環境
  • 控制器與路由
    • 控制器
    • URI 路由設定
    • 控制器過濾器
    • HTTP 訊息
    • Request 類別
    • 訪問請求
    • 內容協商
    • HTTP 類型偽裝
    • 處理 RESTful 請求資源
  • 建構響應
    • 視圖
    • 視圖單元
    • 視圖渲染
    • 視圖布局
    • 視圖解釋器
    • HTML 表格類別
    • HTTP 響應
    • API 響應特性
    • 本土化
    • 用於視圖檔案的 PHP 語法
  • 資料庫操作
    • 快速入門: 範例程式
    • 資料庫組態設定
    • 連接你的資料庫
    • 執行查詢
    • 產生查詢結果
    • 查詢輔助函數
    • 查詢生成器類別
    • 交易
    • 詮釋資料
    • 自訂函數
    • 資料庫事件
    • 資料庫工具
  • 資料模型化
    • 使用 CodeIgniter 的模型
    • 使用實體類別
  • 資料庫管理
    • 資料庫操控與資料庫建構
    • 資料庫遷移
    • 資料庫填充
  • 程式庫參考
    • Caching Driver
    • Cookies
    • CURLRequest Class
    • Email Class
    • 加密服務
    • Working with Files
    • File Collections
    • 誘捕系統類別
    • Image Manipulation Class
    • Pagination
    • Publisher
    • 安全性類別
    • Session Library
    • Throttler
    • Times and Dates
    • Typography
    • Working with Uploaded Files
    • Working with URIs
    • User Agent Class
    • Validation
  • 輔助函數
    • 陣列輔助函數
    • Cookie 輔助函數
    • 日期輔助函數
    • 檔案系統輔助函數
    • 表單輔助函數
    • HTML Helper
    • Inflector 輔助函數
    • Number 輔助函數
    • 安全性輔助函數
    • Test Helper
    • Text Helper
    • URL Helper
    • XML 輔助函數
  • 測試
    • 入門
    • 資料庫測試
    • Generating Data
    • 控制器測試
    • HTTP 特性測試
    • 測試響應
    • 基準測試
    • 偵錯與除錯應用程式
    • Mocking
  • 使用命令列介面
    • 透過命命列執行
    • 自訂命令列介面指令
    • CLI 產生器
    • 命令列程式庫
    • CLI 請求類別
  • 擴充 CodeIgniter
    • 建立核心系統類別
    • 替換常用功能
    • 事件
    • 擴充控制器
    • 認證方式
    • 為 CodeIgniter 貢獻
  • CodeIgniter4 文件翻譯
    • 詞彙對照表
    • 翻譯貢獻者
CodeIgniter4
  • Docs »
  • 程式庫參考 »
  • Pagination

Pagination¶

CodeIgniter provides a very simple, but flexible pagination library that is simple to theme, works with the model, and capable of supporting multiple paginators on a single page.

  • Loading the Library
  • Paginating Database Results
    • Paginating Multiple Results
    • Setting Page Manually
    • Specifying the URI Segment for Page
    • Manual Pagination
    • Paginating with Only Expected Queries
  • Customizing the Links
    • View Configuration
    • Creating the View

Loading the Library¶

Like all services in CodeIgniter, it can be loaded via Config\Services, though you usually will not need to load it manually:

$pager = \Config\Services::pager();

Paginating Database Results¶

In most cases, you will be using the Pager library in order to paginate results that you retrieve from the database. When using the Model class, you can use its built-in paginate() method to automatically retrieve the current batch of results, as well as set up the Pager library so it’s ready to use in your controllers. It even reads the current page it should display from the current URL via a page=X query variable.

To provide a paginated list of users in your application, your controller’s method would look something like:

<?php

namespace App\Controllers;

use CodeIgniter\Controller;

class UserController extends Controller
{
    public function index()
    {
        $model = new \App\Models\UserModel();

        $data = [
            'users' => $model->paginate(10),
            'pager' => $model->pager,
        ];

        echo view('users/index', $data);
    }
}

In this example, we first create a new instance of our UserModel. Then we populate the data to send to the view. The first element is the results from the database, users, which is retrieved for the correct page, returning 10 users per page. The second item that must be sent to the view is the Pager instance itself. As a convenience, the Model will hold on to the instance it used and store it in the public class variable, $pager. So, we grab that and assign it to the $pager variable in the view.

Within the view, we then need to tell it where to display the resulting links:

<?= $pager->links() ?>

And that’s all it takes. The Pager class will render First and Last page links, as well as Next and Previous links for any pages more than two pages on either side of the current page.

It is important to be aware that the library pattern for Next and Previous is different from what is used in the traditional way of paging results.

Next and Previous here is linked to the group of links to be displayed in the pagination structure, and not to the next or previous page of records.

If you prefer a simpler output, you can use the simpleLinks() method, which only uses 「Older」 and 「Newer」 links, instead of the details pagination links:

<?= $pager->simpleLinks() ?>

Behind the scenes, the library loads a view file that determines how the links are formatted, making it simple to modify to your needs. See below for details on how to completely customize the output.

Paginating Multiple Results¶

If you need to provide links from two different result sets, you can pass group names to most of the pagination methods to keep the data separate:

// In the Controller
public function index()
{
    $userModel = new \App\Models\UserModel();
    $pageModel = new \App\Models\PageModel();

    $data = [
        'users' => $userModel->paginate(10, 'group1'),
        'pages' => $pageModel->paginate(15, 'group2'),
        'pager' => $userModel->pager,
    ];

    echo view('users/index', $data);
}

// In the views:
<?= $pager->links('group1') ?>
<?= $pager->simpleLinks('group2') ?>

Setting Page Manually¶

If you need to specify which page of results to return you can specify the page as the 3rd argument. This can be handy when you have a different manner than the default $_GET varibable to control which page to show.

$userModel = new \App\Models\UserModel();
$page = 3;

$users = $userModel->paginate(10, 'group1', $page);

Specifying the URI Segment for Page¶

It is also possible to use a URI segment for the page number, instead of the page query parameter. Simply specify the segment number to use as the fourth argument. URIs generated by the pager would then look like https://domain.tld/model/[pageNumber] instead of https://domain.tld/model?page=[pageNumber].

$users = $userModel->paginate(10, 'group1', null, 3);

Please note: $segment value cannot be greater than the number of URI segments plus 1.

Manual Pagination¶

You may find times where you just need to create pagination based on known data. You can create links manually with the makeLinks() method, which takes the current page, the number of results per page, and the total number of items as the first, second, and third parameters, respectively:

<?= $pager->makeLinks($page, $perPage, $total) ?>

This will, by default, display the links in the normal manner, as a series of links, but you can change the display template used by passing in the name of the template as the fourth parameter. More details can be found in the following sections.

<?= $pager->makeLinks($page, $perPage, $total, 'template_name') ?>

It is also possible to use a URI segment for the page number, instead of the page query parameter, as described in the previous section. Specify the segment number to use as the fifth parameter to makeLinks().

<?= $pager->makeLinks($page, $perPage, $total, 'template_name', $segment) ?>

Please note: $segment value cannot be greater than the number of URI segments plus 1.

If you in need to show many pagers on one page then additional parameter which will define a group could be helpful:

$pager = service('pager');
$pager->setPath('path/for/my-group', 'my-group'); // Additionally you could define path for every group.
$pager->makeLinks($page, $perPage, $total, 'template_name', $segment, 'my-group');

Pagination library uses page query parameter for HTTP queries by default (if no group or default group name given) or page_[groupName] for custom group names.

Paginating with Only Expected Queries¶

By default, all GET queries are shown in the pagination links.

For example, when accessing the URL http://domain.tld?search=foo&order=asc&hello=i+am+here&page=2, the page 3 link can be generated, along with the other links, as follows:

echo $pager->links();
// Page 3 link: http://domain.tld?search=foo&order=asc&hello=i+am+here&page=3

The only() method allows you to limit this just to queries already expected:

echo $pager->only(['search', 'order'])->links();
// Page 3 link: http://domain.tld?search=foo&order=asc&page=3

The page query is enabled by default. And only() acts in all pagination links.

Customizing the Links¶

View Configuration¶

When the links are rendered out to the page, they use a view file to describe the HTML. You can easily change the view that is used by editing app/Config/Pager.php:

public $templates = [
    'default_full'   => 'CodeIgniter\Pager\Views\default_full',
    'default_simple' => 'CodeIgniter\Pager\Views\default_simple',
];

This setting stores the alias and namespaced view paths for the view that should be used. The default_full and default_simple views are used for the links() and simpleLinks() methods, respectively. To change the way those are displayed application-wide, you could assign a new view here.

For example, say you create a new view file that works with the Foundation CSS framework, and you place that file at app/Views/Pagers/foundation_full.php. Since the application directory is namespaced as App, and all directories underneath it map directly to segments of the namespace, you can locate the view file through it’s namespace:

'default_full'   => 'App\Views\Pagers\foundation_full',

Since it is under the standard app/Views directory, though, you do not need to namespace it since the view() method can locate it by filename. In that case, you can simply give the sub-directory and file name:

'default_full'   => 'Pagers/foundation_full',

Once you have created the view and set it in the configuration, it will automatically be used. You don’t have to replace the existing templates. You can create as many additional templates as you need in the configuration file. A common situation would be needing different styles for the frontend and the backend of your application.

public $templates = [
    'default_full'   => 'CodeIgniter\Pager\Views\default_full',
    'default_simple' => 'CodeIgniter\Pager\Views\default_simple',
    'front_full'     => 'App\Views\Pagers\foundation_full',
];

Once configured, you can specify it as a the last parameter in the links(), simpleLinks(), and makeLinks() methods:

<?= $pager->links('group1', 'front_full') ?>
<?= $pager->simpleLinks('group2', 'front_full') ?>
<?= $pager->makeLinks($page, $perPage, $total, 'front_full') ?>

Creating the View¶

When you create a new view, you only need to create the code that is needed for creating the pagination links themselves. You should not create unnecessary wrapping divs since it might be used in multiple places and you only limit their usefulness. It is easiest to demonstrate creating a new view by showing you the existing default_full template:

<?php $pager->setSurroundCount(2) ?>

<nav aria-label="Page navigation">
    <ul class="pagination">
    <?php if ($pager->hasPrevious()) : ?>
        <li>
            <a href="<?= $pager->getFirst() ?>" aria-label="<?= lang('Pager.first') ?>">
                <span aria-hidden="true"><?= lang('Pager.first') ?></span>
            </a>
        </li>
        <li>
            <a href="<?= $pager->getPrevious() ?>" aria-label="<?= lang('Pager.previous') ?>">
                <span aria-hidden="true"><?= lang('Pager.previous') ?></span>
            </a>
        </li>
    <?php endif ?>

    <?php foreach ($pager->links() as $link) : ?>
        <li <?= $link['active'] ? 'class="active"' : '' ?>>
            <a href="<?= $link['uri'] ?>">
                <?= $link['title'] ?>
            </a>
        </li>
    <?php endforeach ?>

    <?php if ($pager->hasNext()) : ?>
        <li>
            <a href="<?= $pager->getNext() ?>" aria-label="<?= lang('Pager.next') ?>">
                <span aria-hidden="true"><?= lang('Pager.next') ?></span>
            </a>
        </li>
        <li>
            <a href="<?= $pager->getLast() ?>" aria-label="<?= lang('Pager.last') ?>">
                <span aria-hidden="true"><?= lang('Pager.last') ?></span>
            </a>
        </li>
    <?php endif ?>
    </ul>
</nav>

setSurroundCount()

In the first line, the setSurroundCount() method specifies than we want to show two links to either side of the current page link. The only parameter that it accepts is the number of links to show.

hasPrevious() & hasNext()

These methods return a boolean true if there are more links that can be displayed on either side of the current page, based on the value passed to setSurroundCount. For example, let’s say we have 20 pages of data. The current page is page 3. If the surrounding count is 2, then the following links would show up in the list: 1, 2, 3, 4, and 5. Since the first link displayed is page one, hasPrevious() would return false since there is no page zero. However, hasNext() would return true since there are 15 additional pages of results after page five.

getPrevious() & getNext()

These methods return the URL for the previous or next pages of results on either side of the numbered links. See the previous paragraph for a full explanation.

getFirst() & getLast()

Much like getPrevious() and getNext(), these methods return links to the first and last pages in the result set.

links()

Returns an array of data about all of the numbered links. Each link’s array contains the uri for the link, the title, which is just the number, and a boolean that tells whether the link is the current/active link or not:

$link = [
    'active' => false,
    'uri'    => 'http://example.com/foo?page=2',
    'title'  => 1,
];

In the code presented for the standard pagination structure, the methods getPrevious() and getNext() are used to obtain the links to the previous and next pagination groups respectively.

If you want to use the pagination structure where prev and next will be links to the previous and next pages based on the current page, just replace the getPrevious() and getNext() methods with getPreviousPage() and getNextPage(), and the methods hasPrevious() and hasNext() by hasPreviousPage() and hasNextPage() respectively.

See following an example with these changes:

<nav aria-label="<?= lang('Pager.pageNavigation') ?>">
    <ul class="pagination">
        <?php if ($pager->hasPreviousPage()) : ?>
            <li>
                <a href="<?= $pager->getFirst() ?>" aria-label="<?= lang('Pager.first') ?>">
                    <span aria-hidden="true"><?= lang('Pager.first') ?></span>
                </a>
            </li>
            <li>
                <a href="<?= $pager->getPreviousPage() ?>" aria-label="<?= lang('Pager.previous') ?>">
                    <span aria-hidden="true"><?= lang('Pager.previous') ?></span>
                </a>
            </li>
        <?php endif ?>

        <?php foreach ($pager->links() as $link) : ?>
            <li <?= $link['active'] ? 'class="active"' : '' ?>>
                <a href="<?= $link['uri'] ?>">
                    <?= $link['title'] ?>
                </a>
            </li>
        <?php endforeach ?>

        <?php if ($pager->hasNextPage()) : ?>
            <li>
                <a href="<?= $pager->getNextPage() ?>" aria-label="<?= lang('Pager.next') ?>">
                    <span aria-hidden="true"><?= lang('Pager.next') ?></span>
                </a>
            </li>
            <li>
                <a href="<?= $pager->getLast() ?>" aria-label="<?= lang('Pager.last') ?>">
                    <span aria-hidden="true"><?= lang('Pager.last') ?></span>
                </a>
            </li>
        <?php endif ?>
    </ul>
</nav>

hasPreviousPage() & hasNextPage()

This method returns a boolean true if there are links to a page before and after, respectively, the current page being displayed.

Their difference to hasPrevious() and hasNext() is that they are based on the current page while hasPrevious() and hasNext() are based on the set of links to be displayed before and after the current page based on the value passed in setSurroundCount.

getPreviousPage() & getNextPage()

These methods return a URL for the previous and next pages in relation to the current page being displayed, unlike getPrevious() and getNext() that return the URL for the previous or next pages of results on either side of the numbered links. See the previous paragraph for a full explanation.

If you want page numbers instead of URLs, you can use the following methods:

getPreviousPageNumber() & getNextPageNumber()

These methods return the page number for the previous or next pages in relation to the current page being displayed.

getFirstPageNumber() & getLastPageNumber()

These methods return page numbers to the first and last pages in the result set.

getCurrentPageNumber()

This method returns the page number of the current page.

getPageCount()

This method returns total number of pages.

Next Previous

© Copyright 2019-2021 CodeIgniter 基金會 | 國立高雄師範大學軟體工程與管理學系 SDPM 實驗室譯製 最後更新於 2021年12月25日。

Built with Sphinx using a theme provided by Read the Docs.