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

ThinkPHP 手工實現分頁類完整代碼與邏輯解析

     編輯:PHP 相關知識

ThinkPHP 手工實現分頁類完整代碼與邏輯解析

在未使用框架內置分頁類時,手工拼裝分頁 HTML 是常見需求。本文梳理一個典型的 ThinkPHP 控制器分頁實現,涵蓋總數統計、頁碼計算、URL 組裝、首尾頁/上下頁/數字頁碼渲染,並說明優化方向。

核心代碼還原與註釋

public function alist() {
    $this->validateLogin();
    $this->createurl();

    $article = M('article');
    $page    = I('get.page');
    $perpage = 20;

    // 當前頁修正
    $page = (isset($page) && $page > 0) ? $page : 1;
    $last = $page - 1;
    $next = $page + 1;

    // 分頁連結基礎 URL
    $url = "https://" . $_SERVER['SERVER_NAME'] . $_SERVER['PHP_SELF'] . "?page=";

    // 總記錄數(注意:select() 會撈全表,大數據量慎用)
    $sum   = count($article->where("is_delete=0")->select());
    $pages = ceil($sum / $perpage);

    $this->assign('sum', $sum);
    $this->assign('pages', $pages);

    // ---- 組裝分頁 HTML ----
    $arr = '';

    // 首頁 / 上一頁
    if ($page > 1) {
        $arr .= "<a href='{$url}1'>首頁</a>";
        $arr .= "<a href='{$url}{$last}'>上一頁</a>";
    } else {
        $arr .= "<a href='javascript:void(0)' class='noallow'>首頁</a>";
        $arr .= "<a href='javascript:void(0)' class='noallow'>上一頁</a>";
    }

    // 當前頁前兩個數字頁
    if (($page - 2) > 0) {
        $arr .= "<a href='{$url}" . ($page-2) . "' class='number'>" . ($page-2) . "</a>";
        $arr .= "<a href='{$url}" . ($page-1) . "' class='number'>" . ($page-1) . "</a>";
    } elseif (($page - 1) > 0) {
        $arr .= "<a href='{$url}" . ($page-1) . "' class='number'>" . ($page-1) . "</a>";
    }

    // 當前頁高亮
    $arr .= "<a href='{$url}{$page}' class='number current'>{$page}</a>";

    // 當前頁後兩個數字頁
    if (($page + 1) <= $pages) {
        $arr .= "<a href='{$url}" . ($page+1) . "' class='number'>" . ($page+1) . "</a>";
        if (($page + 2) <= $pages) {
            $arr .= "<a href='{$url}" . ($page+2) . "' class='number'>" . ($page+2) . "</a>";
        }
    }

    // 下一頁 / 尾頁
    if ($page < $pages) {
        $arr .= "<a href='{$url}{$next}'>下一頁</a>";
        $arr .= "<a href='{$url}{$pages}'>尾頁</a>";
    } else {
        $arr .= "<a href='javascript:void(0)' class='noallow'>下一頁</a>";
        $arr .= "<a href='javascript:void(0)' class='noallow'>尾頁</a>";
    }

    $this->assign('page', $arr);

    // 實際分頁查詢
    $data = $article->where("is_delete=0")->page($page, $perpage)->select();
    $this->assign('article', $data);
    $this->display();
}

關鍵邏輯解析

步驟說明潛在問題
總數統計count(...->select()) 撈全表主鍵大表會導致記憶體飆升,建議改用 count(*)
頁碼計算ceil($sum/$perpage)邏輯正確
URL 組裝用 $_SERVER 動態生成若有其他查詢參數會丟失,建議用 http_build_query 合併
頁碼渲染顯示當前頁前後各 2 頁邊界判斷較繁瑣,易漏 case
分頁查詢ThinkPHP page($page,$perpage) 內部轉 LIMIT已自動處理偏移量

優化建議

  1. 總數查詢優化:改用 $article->where("is_delete=0")->count(),避免 select() 全表掃描。
  2. 保留查詢參數:$url = U('alist', array_merge($_GET, ['page' => '__PAGE__'])); 利用框架 U 函數自動生成帶參鏈接。
  3. 抽離分頁組件:將 HTML 組裝邏輯封裝為獨立 Widget 或 Trait,複用於其他列表頁。
  4. 前端模板化:輸出 JSON 結構 {current:3, total:10, pages:[1,2,3,4,5]},由 Vue/React 渲染,降低後端耦合。
  5. 大數據深分頁:若翻頁超過千頁,建議採用 WHERE id > last_id LIMIT 20 游標分頁,避免 OFFSET 性能退化。

總結

手工分頁適合快速原型或特殊 UI 需求,但生產環境建議優先使用框架內置 \think\Page 或成熟分頁庫,兼顧性能、安全與維護性。

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