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の使い方なのだけれど、
前 1 2 3 4 5 次
という表示は、pager['pages']を使って、組み立てればOK。
結局、ページを渡っていくのに、表示開始番号をスクリプトに渡さないと行けないので、GETパラメータを作ればいいわけで、
という感じでイカガっすか。
GETのパラメータは、実際には開始レコード番号だけでなく、検索時の条件やその他いろいろなものが追加される事が多いが、その辺は省略してある。
mod_rewriteと組み合わせたりしたら、ちょっとカコイイですよ。
実は、PEARには同じようなページ番号表示するためのパッケージに、
Pagerというのがある。うれしいことに日本語訳のマニュアルがある。
Pager
これと、DB_Pagerとの違いは、DB_Pagerは、1...nというアンカーを自分で作らなければならないが、Pagerは、自動でリンクまで作ってくれる。
DB_Pagerが、数値のみを渡して、実際のデータには干渉しないのに対し、Pagerのほうは、表示に使うデータをマルゴト全部渡して、Pagerが必要なデータだけを返してくれる・・というような感じになる。
なんかこっちは扱うデータが大きな場合は、とても効率が悪いような気がする(実際はキャッシュされたり、参照だったりすれば対して負担にはならないのかもしれないが)し、ページ番号を作るためにデータそのもの渡す・・ってのが気に入らない。だからDB_Pagerを好んで使っている。まぁ、好きな方を使えばいいと思う。
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");でとりあえずOK。getDataで戻ってくる値をprint_r()すると、下のような結果となる。($startは0,$limitは20,$totalNumは50とする)
(間の処理は省略)
$pager = DB_Pager::getData($start,$limit,$totalNum,10);
上の連想配列のKeyを見てもらったら、何を示しているかってのはだいたいわかるはず。上の変数の使い方の一例としては・・・(面倒なのでKeyのみ表示)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 )
全 [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;>
GETのパラメータは、実際には開始レコード番号だけでなく、検索時の条件やその他いろいろなものが追加される事が多いが、その辺は省略してある。
mod_rewriteと組み合わせたりしたら、ちょっとカコイイですよ。
実は、PEARには同じようなページ番号表示するためのパッケージに、
Pagerというのがある。うれしいことに日本語訳のマニュアルがある。
Pager
これと、DB_Pagerとの違いは、DB_Pagerは、1...nというアンカーを自分で作らなければならないが、Pagerは、自動でリンクまで作ってくれる。
DB_Pagerが、数値のみを渡して、実際のデータには干渉しないのに対し、Pagerのほうは、表示に使うデータをマルゴト全部渡して、Pagerが必要なデータだけを返してくれる・・というような感じになる。
なんかこっちは扱うデータが大きな場合は、とても効率が悪いような気がする(実際はキャッシュされたり、参照だったりすれば対して負担にはならないのかもしれないが)し、ページ番号を作るためにデータそのもの渡す・・ってのが気に入らない。だからDB_Pagerを好んで使っている。まぁ、好きな方を使えばいいと思う。
コメント (2)
> LIMITを付けてSELECTする前に、まったく同じSQLでLIMITを付けないクエリを実行する必要がある。・・・・しかし、ここの部分はなんか効率が悪い気がする。
"MySQL SQL_CALC_FOUND_ROWS"で、検索かければ解決です。
投稿者: なか | 2006年08月17日 06:57
日時: 2006年08月17日 06:57
コメントありがとうございます。
以前は、PEAR::DBを使う場合は、その指定が便利そうですね。
本家マニュアルによると、
SQL_CALC_FOUND_ROWS と FOUND_ROWS() は MySQL バージョン 4.0.0 以降で使用できる。
出そうです。
仕事で使ってるサイトは、3.x系を使ってるのでダメでした・・
ここ数年は、DB_DataObjectを使ってるので、意識的にSELECTを2回発行することは無いですが、有益な情報ありがとうございました。
投稿者: ANN | 2006年08月18日 14:48
日時: 2006年08月18日 14:48