search
LoginSignup
2

More than 5 years have passed since last update.

posted at

updated at

FuelPHPのPagination(ページネーション)でwhere句とかで絞り込むとき

初カキコ…ども…

FuelPHPのPaginationをwhere句とかで絞り込むとき,こんな感じでやってます.
FuelでORMパッケージ使っている前提で書かせていただきやす…
http://fuelphp.jp/docs/1.9/packages/orm/intro.html
:point_up_tone2: (ORMパッケージは標準で有効にしてもよいのでは…?)

まずFuelPHPのPaginationの基本的な使い方を手順で表すとこんな感じっす…

  1. paginationインスタンスを作る
  2. paginationインスタンスのtotal_itemsプロパティに全件数を設定
  3. per_pageプロパティに1ページあたりに表示する件数を設定
  4. ページ番号を設定
  5. paginationインスタンスからoffset値を取得
  6. クエリビルダー系のメソッドで,取得したoffset値を利用して1ページ分のオブジェクトを取得

という感じです.(わからん)

(公式ドキュメントが一番分かりやすい)
http://fuelphp.jp/docs/1.9/classes/pagination.html

公式ドキュメントのサンプルだと,total_itemsにModel_Post::count()で全件数を設定してますが,これだとwhere句を指定して絞り込みを行ったときなどに,total_itemsに設定した件数と,絞り込んで取得した件数に違いが出てしまいます.total_itemsを元に全体のページ数などが決まるので,絞り込みを行う際は注意が必要っすね

そんなとき,下記のような書き方をするとよさげな感じに動的にtotal_itemsを設定できます.
よーは,先に絞り込み条件を指定したqueryオブジェクトを作成し,それを流用して
countメソッド(total_itemsの設定)とgetメソッド(1ページあたりのオブジェクトの取得)を実行するという感じです

//queryインスタンスの取得
$query = Model_Post::query(); 

//タグでの絞り込み
if(Input::get('tag')){ 
    $query->where('tag', Input::get('tag'));
}
//ワードでの絞り込み
if(Input::get('word')){ 
    $query->where('content', 'LIKE', "%".Input::get('word')."%");
}
//ソート(並び順)が指定された場合
if(Input::get('order_by')){ 
    $query->order_by(Input::get('order_by'), 'DESC');
}

//paginationインスタンスの取得
$pagination = Pagination::forge('mypagination', [
    'pagination_url' => Uri::base(false).'posts',
    'uri_segment'    => 2,
    'per_page'       => 5,
    'total_items'    => $query->count() //ここでcountメソッドを実行する
]);

//countメソッドを実行したqueryオブジェクトを流用
//paginationインスタンスからoffset値を取得しqueryのoffsetに設定
$query->limit($pagination->per_page);
$query->offset($pagination->offset);

//getメソッドを実行して1ページあたりのオブジェクトを取得
$posts = $query->get();

//あとはオブジェクトをviewに渡すなりしちゃって

View側でページのボタンをレンダリングするのはこんな感じ…

<?php if(Pagination::instance('mypagination')){ echo Pagination::instance('mypagination')->render(); } ?>

使い慣れている方したら,だから何だって感じかも知れませんが…(よりよい書き方があれば教えてもらえたら嬉しい)

ちなみに私はFuelPHPでORM利用する際は,基本的にはqueryメソッドを使うようにしています.findはほとんど使いません.
findメソッドはwhere句などで絞り込む場合,第二引数に配列でひたすらぶち込む必要があるので,複雑なことをすると可読性が下がり気味な印象です.queryメソッドなら,先のpagination処理の例で使ったように,分岐や使いまわしが簡単ですし,ステップ実行でデバッグがしやすいです.メソッドチェーンを使えば可読性のよろしいコードが書くこともできます.:grin:
findで書いてqueryで書き直すケースは何回かあったのですが,その逆はあまり無かった気がします.逆にfindメソッドの便利な活用法などあれば知りたいです.(使ってみた感じ,多分,どっちかで"しか"出来ないことはほとんど無いと思いますが)

IDだけ指定してオブジェクトを取得する場合findのほうが簡潔かな…


Model_Idol::find(765);

Model_Idol::query()->where('id', 765)->get_one();

SQL文を直でゴリつかせるのはORMを使うメリットがなくなるのであまり使いません.
as_objectとかいう関数を使うとSQLの文字列からModelオブジェクトを取得する方法があるようですが(使ってないのでどういう仕組みかは謎…)

そんな訳でqueryメソッド限定で書かせていただ感じです…

FuelのORMは割とSQLに近い書き味な印象なのでORM入門にはよいかも知れません.
ORMを使うにしても,内部でどんなSQLが実行されるか想像できたほうが強いですね.:muscle_tone2:

以上レポっす:wave_tone1:

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
2