« セセリ×バッタ | メイン | iPod Photo »

PEAR DB_Pager

2006年4月追記---
DB_Pager は古いので、Pagerを使った方法を↓に書きました。
Pear::Pagerの使い方
こちらのほうが使い勝手がよいので、↑がオススメです。
---

以前、少しだけDB_Pager使い方を書いたのだけれど、追加してもう少し使い方など。Web上に意外と使い方を記載している所がないので。誰かの役に立てば&自分メモ。

基本的な使い方は、前のエントリーを見てください。
see.Nega Diary: PEARのDB_Pager

普通データベースからデータを引っ張ってくる場合、SQLで全レコードデータを持ってきて、PHP側で1〜30件まで・・というような使い方はしない。MySQLの場合、LIMITが使えるので、結果レコードのうち、何レコードめから、何件を持ってくる・・という使い方ができる。

例えば、全部で1000レコードあり、そのうち、500レコードが検索の条件にマッチしたとする。そのうち、20件ずつを画面に表示するとする。

SQLだと、 SELECT * FROM table WHERE id is not null LIMIT 100,20
(idがnullじゃないレコードを、100件目から20コ寄こしなさい)
という感じか・・・。

DB_Pagerに必要なパラメータは、この1000レコードという情報であるが、SELECTした後のnumRows()は、上記のLIMITで指定した件数が返してくる。だから、LIMITを付けてSELECTする前に、まったく同じSQLでLIMITを付けないクエリを実行する必要がある。・・・・しかし、ここの部分はなんか効率が悪い気がする。だれか良い方法教えて。>PEAR,SQLのエロい人!

で、その辺のSQL周りはガッ!と割愛して、、、DB_Pearの使い方なのだけれど、
include_once("DB_Pager/Pager.php");
(間の処理は省略)
$pager = DB_Pager::getData($start,$limit,$totalNum,10);
でとりあえずOK。getDataで戻ってくる値をprint_r()すると、下のような結果となる。($startは0,$limitは20,$totalNumは50とする)
Array
(
 [numpages] => 3
 [firstpage] => 1
 [lastpage] => 3
 [pages] => Array
 (
   [1] => 0
   [2] => 20
   [3] => 40
  )
[current] => 1
[maxpages] => 10
[prev] => 
[next] => 20
[remain] => 20
[to] => 20
[numrows] => 50
[from] => 1
[limit] => 20
)
上の連想配列のKeyを見てもらったら、何を示しているかってのはだいたいわかるはず。上の変数の使い方の一例としては・・・(面倒なのでKeyのみ表示)
全 [numrows]件
現在、[from件]から、[to]件を表示中
全[numpages]ページ。現在 [current]ページを表示中
で、肝心の、

前 1 2 3 4 5 次

という表示は、pager['pages']を使って、組み立てればOK。
結局、ページを渡っていくのに、表示開始番号をスクリプトに渡さないと行けないので、GETパラメータを作ればいいわけで、
if(isset($pager['prev'])){
  // 前ページへのリンク
  $buff .= sprintf(" <a href=list.php?start=%s>前</a> ",$pager['prev']);
}
// 1 2 3 4 5 ..へのリンクを作る
foreach($pager['pages'] as $key => $val){
  if($key == $pager['current']){
    // カレントページ
    $buff .= " <b>" . $key . "</b> ";
  }else{
    // それ以外
    $buff .= sprintf(" <a href=list.php?start=%s>%d</a> ",$val,$key);
  }
}
if(isset($pager['next'])){
  // 次ページへのリンク
  $buff .= sprintf(" <a href=list.php?start=%s>次</a> ",$pager['next']);
}

echo $buff;>
dbpager.png という感じでイカガっすか。
GETのパラメータは、実際には開始レコード番号だけでなく、検索時の条件やその他いろいろなものが追加される事が多いが、その辺は省略してある。
mod_rewriteと組み合わせたりしたら、ちょっとカコイイですよ。

実は、PEARには同じようなページ番号表示するためのパッケージに、
Pagerというのがある。うれしいことに日本語訳のマニュアルがある。
Pager
これと、DB_Pagerとの違いは、DB_Pagerは、1...nというアンカーを自分で作らなければならないが、Pagerは、自動でリンクまで作ってくれる。
DB_Pagerが、数値のみを渡して、実際のデータには干渉しないのに対し、Pagerのほうは、表示に使うデータをマルゴト全部渡して、Pagerが必要なデータだけを返してくれる・・というような感じになる。
なんかこっちは扱うデータが大きな場合は、とても効率が悪いような気がする(実際はキャッシュされたり、参照だったりすれば対して負担にはならないのかもしれないが)し、ページ番号を作るためにデータそのもの渡す・・ってのが気に入らない。だからDB_Pagerを好んで使っている。まぁ、好きな方を使えばいいと思う。

トラックバック

このエントリーのトラックバックURL:
http://www.ironhearts.com/diary/mt-tb-ih.cgi/26

この一覧は、次のエントリーを参照しています: PEAR DB_Pager:

» Pear::Pagerの使い方 送信元 Nega Diary
以前、DB_Pagerの使い方というので記事を書いたけれど、実はDB_Pager 自体がそうとう古く、メンテもされてないので、これからは PEAR :: Package :: Pager 使うのが吉。 ということで、早速、使い方を調べて、制作中のアプリに組み込んでみました。 require_once "Pager/P... [詳しくはこちら]

コメント (2)

なか:

> LIMITを付けてSELECTする前に、まったく同じSQLでLIMITを付けないクエリを実行する必要がある。・・・・しかし、ここの部分はなんか効率が悪い気がする。
"MySQL SQL_CALC_FOUND_ROWS"で、検索かければ解決です。

ANN:

コメントありがとうございます。

以前は、PEAR::DBを使う場合は、その指定が便利そうですね。

本家マニュアルによると、

SQL_CALC_FOUND_ROWS と FOUND_ROWS() は MySQL バージョン 4.0.0 以降で使用できる。

出そうです。

仕事で使ってるサイトは、3.x系を使ってるのでダメでした・・

ここ数年は、DB_DataObjectを使ってるので、意識的にSELECTを2回発行することは無いですが、有益な情報ありがとうございました。

コメントを投稿

2008年10月

      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

最近のコメント

小優 on 日々の記録: DELL4600Cで
よしぞう on 日々の記録: 4600C 表記の対
よしぞう on 日々の記録: 4600C 表記の対
on MySQL後で調べるメモ: DB接続後 目的のS
on 日々の記録: 「無くなった留め具」
on JavaScriptでクロスドメイン: >しかし、こういう小
junp on iMovieで静止画を取り込むと荒い: すいません困ってます
う〜ん・・・ on 素朴な疑問: にょうをした、きたな
困ってました on ATOKとIME2005が勝手に切り替わる問題: 何故か勝手に切り替わ
go on 日々の記録: 4600C、同じ症状

アーカイブ