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

Zend Framework Zend_Db 分頁查詢完整實作範例

     編輯:PHP 相關知識

Zend Framework 1.x 的 Zend_Db 元件提供物件導向的 SQL 建構器 (Zend_Db_Select) 與分頁支援。本文展示完整的分頁查詢流程:從資料庫連線、總筆數統計、Select 物件建構、分頁邏輯到前端頁碼輸出。

完整程式碼範例

<?php
// 取得當前頁碼
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;

// 載入類別
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Db');
Zend_Loader::loadClass('Zend_Db_Statement_Pdo');

// 資料庫配置
$config = [
    'host'     => '127.0.0.1',
    'username' => 'root',
    'password' => '111',
    'dbname'   => 'test',
    'profiler' => true
];

// 建立資料庫連線 (PDO_Mysql)
$db = Zend_Db::factory('PDO_Mysql', $config);
$db->query('SET NAMES utf8');

// 1. 取得總筆數
$total = $db->fetchOne('SELECT COUNT(*) FROM gongsi');

// 2. 分頁參數
$perPage = 50;
$totalPages = ceil($total / $perPage);

// 3. 建構 Select 物件
$select = $db->select();
$select->from('sanguo', [
    's_sheng as 省份',
    'sum(s_gongzi) as 總工資',
    'min(s_gongzi) as 最低工資',
    'max(s_gongzi) as 最高工資',
    'avg(s_gongzi) as 平均工資'
]);
// 可選條件
// $select->where('s_gongzi >= ?', 3000);
// $select->where("s_sheng = ?", '河北');
$select->group('s_sheng');
$select->having('最高工資 > ?', 10000);
$select->order('最高工資 DESC');

// 4. 套用分頁 (頁碼從 1 開始,內部自動計算 offset)
$select->limitPage($page, $perPage);

// 5. 執行查詢
$results = $db->fetchAll($select);

// 6. 輸出表格
echo "";
echo "";
foreach ($results as $row) {
    echo "";
    foreach ($row as $val) {
        echo "";
    }
    echo "";
}

// 7. 輸出分頁導航
echo "
省份總工資最低工資最高工資平均工資
$val
"; echo "首頁 "; if ($page > 1) echo "上頁 "; for ($i = 1; $i <= min(15, $totalPages); $i++) { echo "$i "; } if ($page < $totalPages) echo "下頁 "; echo "末頁"; echo "
"; ?>

關鍵技術點解析

Zend_Db_Select 流暢介面

  • 方法鏈式調用:from()、where()、group()、having()、order()、limitPage()。
  • 自動識別子引用:欄位名、表名自動加反引號,防止保留字衝突。
  • 參數綁定:where('col = ?', $val) 自動處理引號與轉義,防 SQL 注入。

limitPage() 內部邏輯

// 相當於
$select->limit($perPage, ($page - 1) * $perPage);
// 即 LIMIT offset, count

頁碼從 1 起算,內部自動換算 offset,開發者無需手動計算。

Profiler 效能分析

配置 'profiler' => true 後,可透過 $db->getProfiler() 取得查詢耗時、SQL 文本等資訊,利於優化。

分頁導航優化建議

  • 省略號跳頁:頁碼過多時顯示 1 ... 5 6 7 ... 100,避免過長導航列。
  • URL 保持其他查詢參數:http_build_query(array_merge($_GET, ['page' => $i]))。
  • SEO 友善:加入 rel="prev/next"、canonical 標籤。
  • AJAX 無限滾動:回傳 JSON,前端動態追加。

常見陷阱

  • GROUP BY 與分頁:MySQL GROUP BY 配合 LIMIT 可能導致結果不穩定,建議加上確定性 ORDER BY。
  • 大偏移量效能:LIMIT 100000, 50 需掃描前 10 萬行。百萬級資料建議用「游標分頁」(WHERE id > last_id)替代。
  • 總筆數查詢優化:複雜查詢的 COUNT(*) 可能很慢,可考慮快取總數、使用近似值或延遲載入。

現代替代方案

  • Laminas Db (ZF3+):相同 API,支援 PHP 7/8。
  • Doctrine DBAL:功能更強、型別系統更完善。
  • Eloquent (Laravel) / Cycle ORM:Active Record 風格,分頁內建 paginate()。

結語

Zend_Db_Select 的 limitPage() 讓分頁查詢變得直觀易維護。結合 Profiler 與參數綁定,能寫出安全、高效、可測試的資料存取層。理解其生成的 SQL 結構,有助於在必要時手寫優化查詢。

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