首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

ThinkPHP 分頁帶條件查詢實戰:保持 URL 參數與分頁鏈接正確

     編輯:PHP 相關知識

ThinkPHP 分頁類進階用法:條件保持、自定義樣式與 AJAX 分頁

ThinkPHP 內建 Page 類支援帶條件分頁,但常見問題是翻頁後查詢條件丟失。本文詳細講解如何正確傳遞 WHERE 條件、自定義分頁模板、實現無刷新分頁。

基礎用法:帶 WHERE 條件分頁

<?php
// 控制器方法
public function index() {
    $map = []; // 條件數組
    
    // 1. 從請求獲取查詢參數並構建條件
    $keyword = input('get.keyword/s', '');
    if ($keyword) {
        $map['title|content'] = ['like', "%$keyword%"];
    }
    $status = input('get.status/d', 0);
    if ($status) {
        $map['status'] = $status;
    }
    
    // 2. 實例化分頁類(ThinkPHP 5/6 語法)
    $list = Db::name('announcement')
        ->where($map)
        ->order('announcement_id DESC')
        ->paginate(15, false, [
            'query' => request()->get(), // 關鍵:自動攜帶所有 GET 參數生成分頁鏈接
            'var_page' => 'page',
        ]);
    
    // 3. 模板賦值
    $this->assign([
        'list'   => $list,
        'keyword' => $keyword,
        'status'  => $status,
    ]);
    return $this->fetch();
}
?>

關鍵點:paginate() 第三個參數 'query' => request()->get() 會將當前所有 GET 參數自動拼接到分頁鏈接中,翻頁時條件不丟失。

模板渲染:默認與自定義分頁樣式

<!-- 模板文件 -->
<div class="pagination">
    {$list->render()} 
    <!-- 或自定義模板 -->
    {$list->appends(request()->get())->render('custom_pagination')}
</div>

自定義分頁模板(application/index/view/custom_pagination.html):

<nav aria-label="Page navigation">
    <ul class="pagination">
        <li class="page-item {if !$list->hasPages() || $list->currentPage() == 1}disabled{/if}">
            <a class="page-link" href="{$list->url(1)}">首頁</a>
        </li>
        <li class="page-item {if !$list->hasPages() || !$list->hasPrevious()}disabled{/if}">
            <a class="page-link" href="{$list->previousPageUrl()}">上一頁</a>
        </li>
        
        {for $i = max(1, $list->currentPage()-2); $i <= min($list->lastPage(), $list->currentPage()+2); $i++}
            <li class="page-item {if $list->currentPage() == $i}active{/if}">
                <a class="page-link" href="{$list->url($i)}">{$i}</a>
            </li>
        {/for}
        
        <li class="page-item {if !$list->hasPages() || !$list->hasNext()}disabled{/if}">
            <a class="page-link" href="{$list->nextPageUrl()}">下一頁</a>
        </li>
        <li class="page-item {if !$list->hasPages() || $list->currentPage() == $list->lastPage()}disabled{/if}">
            <a class="page-link" href="{$list->url($list->lastPage())}">尾頁</a>
        </li>
    </ul>
</nav>

進階:圖片按鈕分頁(上一頁/下一頁圖標)

<?php
// 控制器中配置
$page = $list->appends(request()->get());
$page->setConfig('prev', '<img src="/static/img/prev.png" alt="上一頁">');
$page->setConfig('next', '<img src="/static/img/next.png" alt="下一頁">');
$page->setConfig('first', '');
$page->setConfig('last', '');
$page->setConfig('theme', '%UP_PAGE% %DOWN_PAGE%'); // 僅顯示上下頁
$this->assign('page', $page->render());

AJAX 無刷新分頁實現

<!-- 列表容器 -->
<div id="list-container">
    {include file="list_items" /}
</div>

<div id="pagination">
    {$list->render()}
</div>

<script>
// 事件委託綁定分頁鏈接
$('#pagination').on('click', 'a', function(e) {
    e.preventDefault();
    const url = $(this).attr('href');
    if (!url || $(this).parent().hasClass('disabled')) return;
    
    $.get(url, function(html) {
        // 假設後端返回完整頁面,提取列表與分頁部分
        const $html = $($.parseHTML(html));
        $('#list-container').html($html.find('#list-container').html());
        $('#pagination').html($html.find('#pagination').html());
        // 或後端直接返回 JSON {list: ..., pagination: ...}
    });
});
</script>

後端判斷 AJAX 請求返回局部視圖:

<?php
if (request()->isAjax()) {
    return [
        'list'      => $this->fetch('list_items'), // 局部模板
        'pagination' => $list->render(),
    ];
}
return $this->fetch();

手動構建分頁(不使用模型 paginate)

<?php
use think\Paginator;

$total = Db::name('announcement')->where($map)->count();
$page = new Paginator(
    Db::name('announcement')->where($map)->order('id DESC')->limit(15)->select(),
    15,
    $total,
    [
        'query'     => request()->get(),
        'var_page'  => 'page',
        'path'      => url('index'), // 手動指定路徑
    ]
);

常見問題排查

問題原因解決
翻頁後條件丟失未傳遞 query 參數paginate(15, false, ['query' => request()->get()])
分頁鏈接域名錯誤反向代理/負載均衡導致 URL 構建異常配置 app.request.domain 或手動 path => url('index')
總數統計慢大表 COUNT(*) 全表掃描使用緩存總數、近似統計、或分表分庫
AJAX 分頁重複綁定事件每次渲染重新綁定 click使用事件委託 $(document).on('click', '#pagination a', ...)

總結

ThinkPHP 分頁核心在於 條件數組構建 + query 參數傳遞 + 模板渲染 三步。掌握 paginate() 的第三個參數配置、appends() 方法、自定義模板與 AJAX 局部刷新,即可應對 90% 分頁場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved