用 Zend_Db_Select 處理分頁的資料 Query

假設我們有個 table 叫 products , 我們建立一個 class 繼承 Zend_Db_Table 如下

class ProductsModel extends Zend_Db_Table {
    protected $_name = 'products' ;
}

相信會用 Zend_Db_Table 的知道這是什麼物件幹什用的吧 !

若要一次抓出每頁 20 筆資料 , 可能我們會這麼做

$page = $_GET['page'];
$max_rows = 20;
$products_model = new ProductsModel();
$select = $products_model->select()
->limitPage( $page  , $max_rows)
->where('price>?',10)
->order('create_date desc');
$rows = $products_model->fetchAll($select);

以上的程式碼是搭配 Zend Framework 1.5 才能用的 , 自從 1.5 版之後對於 Zend_Db_Table 可以搭配 Zend_Db_Select 物件抓資料 , 所以上面範例是利用 limitPage 指令去抓某頁的資料 , 如果下 echo $select->__toString() 應該會是

SELECT `products`.* FROM`products` WHERE (price>10) LIMIT 20

但是現在還有個問題 , 通常我們也要抓此次 Query 的資料總共有幾筆 , 用上述分頁後 , 就頂多只傳回 20 筆了 ...

該不會真的笨到用 count($rows) 去算總數吧 ....

好加在 Zend_Db_Select 提供了 reset() 指令可以讓我們這麼用

$select->reset(Zend_Db_Select::FROM)
->reset(Zend_Db_Select::COLUMNS)
->reset(Zend_Db_Select::LIMIT_COUNT)
->reset(Zend_Db_Select::LIMIT_OFFSET)
->from( $products_model->info('name') , array('total_rows'=>'count(*)'));
$total_rows = $lotteries_model->fetchRow($select)->total_rows;

哈 .... 這樣是不是很聰明啊 .... 這樣 $total_rows 就是資料總數了  , 如果下 echo $select->__toString() 應該會是

SELECT count(*) AS `total_rows`  FROM`products` WHERE price>10 ORDER BY `create_date` DESC LIMIT 1

這原理很簡單 , 就是利用 reset() 指令把分頁及FROM的區段清除 , 然後重新下 from() 指令就會得到上面的 query 了 , 這樣原本的 WHERE 條件式及 ORDER 的部份仍然保留著 , 是不是很方便啊 ^^

發佈留言