Cakephp ランダムな pagenateを実装する ITかあさん

ITかあさん

Cakephp ランダムな pagenateを実装する

Cakephp ランダムな pagenateを実装しようとすると、次のページに送った時や戻るボタンを押した時、その都度randomが実行されて、どうしても理想的なランダムなページング処理が出来ずに悩んでいましたが、今日その悩みをズバリ解決することが出来ました!x

前置きはそれくらいにして、Cakephp ランダムな pagenateの実装方法です。

結論:Sessionと乱数を使う

ポイントはSessionと乱数を使うこと。seedな考え方が必要だったのです。

1.乱数を発生させる
2.乱数をSessionに保存する。
3.Sessionに保存した乱数を使ってページング処理を実行する

以上です。Sessionの使い方についてはこちらを参考にしてください
『CakePHP』を使ってみる ~11~ セッションの使い方確認 ざ・わーるど.jp@はてな

1.乱数を発生させる

 $seed = mt_rand(0,9999);

2.発生させた乱数をSessionに保存

発生させた乱数をSessionに保存します。
Cakephp1.3ではあらかじめSessionコンポートとして呼び出す必要があります。

var $components = array('Session');

Sessionに関する処理は以下。
Sessionを呼び出して、空だったら、新たにSessionを書き込みます。

if($this->Session->read('seed') == ""){
//以下random seedの処理
$seed = mt_rand(0,9999);
$this->Session->write('seed', $int);
}
$seed = $this->Session->read('seed');

3.Sessionに保存した乱数を使ってページング処理を実行

$this->paginate = array(
'conditions'=>$con,
'order' => array("rand('$seed')"),//エラーにならないよう、外側はダブルクウォーテーション、内側シングル
'limit'=>5,
);

たったこれだけです。

Sessionが無ければ乱数を発生させてそれをSessionに保存する。
Sessionがあればその整数を継続して利用する。

Sessionが有効な間はゼロからランダムになりませんので、乱数を発生させてSessionに保存することが一番大事です。

後は保存したSessionをpagenateのrandの()の中にぶちこんであげるだけです。

一番分かりやすいのは何ページかページを送った後んに戻るボタンを押してみること。
ページを戻しても前に見た時と表示内容に変化がないと思います。

本当に乱数が発生できているかは違うブラウザを2つ立ち上げて確認してみることですね。
それぞれのブラウザが別々の結果を出力出来ていれば成功というわけです。

おまけ:CakePHP以外でランダムページャー

今回はCakephpで実装しましたが、この考え方は例えばPEAR:pagerなどでも実装可能です。
生でSQLを書いてこの処理を実装させるには以下の通り。

order by rand($seed)

ごめんなさい、本当にこれだけです。
ここでもポイントは何らかの形で乱数を必ず一定時間保存するということです。
『ちゃんとしたランダム』を実装してあげるためには、何かで一定時間Sessionを保持してあげるプラグインをかましてあげなければなりません。
発生させた乱数がリロードするごとに変わってしまうのでは、何の意味もないからです。

最後に:ページャー以外でも使ってあげるのがよい

今回のやり方はpagenateのために考えたわけですが、
ランダムって、通常のORDER BY id DESCやASCに比べると取得時間に大幅な時間がかかります。
だいたい5~8倍くらい通常の引っ張り方に比べて速度に差が出てくるので、
ページング処理以外でもランダムで取得してあげているならぜひ実装するのがオススメです。

ランダムなページング処理ってIDの降順、昇順に並べてページングすることほど多くはないですが、全てのデータを平等に見せたいという意味では有効な手段といえそうです。