2007年11月14日

CodeIgniterでページングを実装してみる

前回はActiveRecordクラスを使ってまがりなりにも検索できるところまで書きましたが、今回はいよいよ懸案のページングを実装してみたいとおもいます。

そもそもフレームワークを使ってみようとおもったきっかけは、元の手続き型で書いた汚いスクリプトにSQLのLIMITを使ったページングを実装したい、というのが主な動機だったので、これがうまくいけば個人的にはほぼ満足というか目標達成!みたいなところでもあります。

で、さっそくユーザガイドを丸写しっと。まずControllerのIndex()の先頭付近に(別に先頭じゃなくてもいいとはおもいますが…)
$this->load->library('pagination');

としてページネーションクラスをロードします。

次にページネーションに渡すパラメータを設定します。ユーザガイドには最低限3つの項目とありますのでその通りに…
$config['base_url'] = 'http://localhost/codeigniter/index.php/gappei/index/';
$config['total_rows'] = (とりあえず保留);
$config['per_page'] = '10';

total_rowsはDBから総件数を取得してこないとならないのでとりあえず保留。per_pageはゆくゆくはユーザが指定できるようにしたいですが、これもとりあえず10件で、base_urlは“完全なURL”と書いてありますが、例えばうちの設定だとhttp://localhost/codeigniter/http://localhost/codeigniter/index.php/gappei/index/が呼び出されるようなルーティング設定にしてますが、この部分には後者の完全なURLを書かないとまずいみたいです。

そしてconfig配列をページネーションに渡します。
$this->pagination->initialize($config);

次にVIEWに生成されたページングリンクを出力するコードを…
$this->pagination->create_links();

次に保留にしておいた総件数の取得ですが、まず前回のクエリを組み立てている部分のコード…
//結果取得SQL
$this->db->select('nid, pref, nc, o.id oid, o.city oc, gdate');
$this->db->from( "(SELECT DISTINCT nid, pref, nc, yomi, gdate
FROM cities
WHERE nc like '%".$data['newcity']."%'
LIMIT 0, 10) AS vn");
$this->db->join('newcities_oldcities j', 'vn.nid = j.newcity_id');
$this->db->join('oldcities o', 'o.id = j.oldcity_id');

普通総件数を取得したい場合は、この後…
$count = $this->db->get()->num_rows();

でよいとおもいますが、前回までで散々述べてきたとおり、欲しい件数は新市町村の数になるので、このままではいけません。

具体的にはFROM句のサブクエリ部分でのLIMITを適用する前の件数が欲しいわけです。なのでまずサブクエリ部分(LIMITの前まで)を抽出してみます。
SELECT DISTINCT nid, pref, nc, yomi, gdate
FROM cities
WHERE nc like '%".$data['newcity']."%'

で、これをActiveRecord風に書き直します。
$this->db->select('DISTINCT nid, pref, nc, yomi, gdate');
$this->db->from('cities');
$this->db->like('nc', $data['newcity']);

db->like()はキーと値を渡してやると自動的にWHERE句を作ってくれます。こういうのはSQL直書きよりもイイですね。

そしてSQLを発行して件数を数えます。
$count = $this->db->get()->num_rows();

で、countの値を先ほど保留にしておいたtotal_rowsに設定します。
$config['total_rows'] = $count;

これで準備ができたのでブラウザをリロードしてみます。

paging.pngこの画像は3ページ目を表示しているところです。クエリーも総件数取得とデータ取得の2回実行されているのがわかるとおもいます。でもよく見るとページングのリンク部分は確かに3という数字がボールドリンクなしになっていて現在の表示ページが3ページ目だということを表していますが、データをみると1ページ目のデータが出力されています。

とおもってよく見るとLIMIT句のoffset値をちゃんと設定してませんでした(--;ここはページネーションで生成されたURLの第3セグメントを入れないとなりません。ということでデータ取得クエリのFROM句の部分を
$this->db->from(  "(SELECT DISTINCT nid, pref, nc, yomi, gdate
FROM cities
WHERE nc like '%".$data['newcity']."%'
LIMIT ".$offset.", 10) AS vn");

に変更します。そしてindex()が引数を取るように…
function index($offset=0)

と書き換えます。

paging2.pngこんどはきちんと3ページ目が表示されているようです。SQLもちゃんとLIMIT 20, 10になっているのがわかるとおもいます。これで一応ページングは実装できた・・・・・かのように見えますが、実は重大な落とし穴があります(--;

続きは次回
ラベル:codeigniter
posted by ciallost at 18:45| Comment(2) | TrackBack(0) | 日記 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
ランジェリー
Posted by ヴィクトリアズシークレット 日本 at 2013年08月05日 14:11
chan luu ブレス
Posted by crocs セール at 2013年08月07日 01:15
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック