FuelPHPでデータの検索(実践編その4)

今日は、FuelPHPでデータ検索する方法を調べてみたいと思います。前回の『FuelPHPでデータの削除』で、テンプレートファイルを作成し、そのテンプレートファイルの中に検索窓を作成しました。その検索窓からデータを検索してみたいと思います。

1. searchビューを作成しても構わないのですが、indexビューと全く変わりませんので、indexビューで代用したいと思います。POST送信の場合は送られたデータを含んでいる値の検索をかけ、POST送信以外は全データを表示するようにします。indexビューを下記のように修正します。

app/classes/controller/collection.php 

public function action_index(){
 //もし空白でない値がPOST送信されたら
 if(Input::method() == 'POST' && Input::post('search')){
 $search='%'.Input::post('search').'%';
 //タイトル名及び備考から該当データを検索
 $query=DB::select()->from('collections')
 ->where('title','LIKE',$search)->or_where('note','LIKE',$search)
 ->execute();
 //テンプレートファイルの呼び出し
 $this->template->content=View::forge('collection/index');
 //テンプレートファイルに値の引き渡し
 $this->template->content->set('query',$query->as_array());
 }else{
 //Collectionsテーブルのデータを降順で取得
 $query=DB::select()->from('collections')->order_by('modified','desc')->execute();
 //テンプレートファイルの呼び出し
 $this->template->content=View::forge('collection/index');
 //データベースをテンプレートに渡す
 $this->template->content->set('query',$query->as_array());
 }
 }

2. それではブラウザから『愛』と入力してEnterしてみます。タイトル名と備考から『愛』という文字を含んでいるデータの一覧が表示されました。タイトルに『愛』の文字が含まれていない『ショーシャンクの空に』をクリックしてみます。

3. 備考の中に『愛』という文字が含まれていました。コードの中のコメントを確認していただければほとんど分かると思いますので、解説は省略いたします。

複合語検索

4. 普通の検索だけならあまりにも簡単に終わってしまいますので、質問の多い『複数の単語をスペースキーで区切って検索する複合語検索』についても調べてみましょう。

5. 方法としては、スペース(全角又は半角)が含まれている部分でデータを区切って配列に代入し、配列の数だけ条件を追加すればいいと思います。それでは、実際にやってみます。

6. 下記に修正したindexアクションを記述します。

app/classes/controller/collection.php

public function action_index(){
 //もし空白でない値がPOST送信されたら
 //if(Input::method() == 'POST' && Input::post('search')!=''){
 if(Input::method() == 'POST' && Input::post('search')){
 $search=Input::post('search');
 //検索文字を空白(全角又は半角)で区切って配列に代入
 $keywords=preg_split('/ |\\s/',$search);
 //配列の数だけ繰り返し
 foreach($keywords as $key=>$keyword){
 $keywords[$key]=' (TITLE LIKE "%'.$keyword.'%"';
 $keywords[$key].=' OR NOTE LIKE "%'.$keyword.'%")';
 }
 //配列のKeywordsをANDで区切って$whereに代入
 $where=implode(' AND',$keywords);
 //SQL文の生成と発行
 $sql=sprintf("SELECT * FROM collections WHERE %s",$where);
 $query=DB::query($sql)->execute();
 //テンプレートファイルの呼び出し
 $this->template->content=View::forge('collection/index');
 //テンプレートファイルに値の引き渡し
 $this->template->content->set('query',$query->as_array());
 echo DB::last_query();
 }else{
 //Collectionsテーブルのデータを降順で取得
 $query=DB::select()->from('collections')->order_by('modified','desc')->execute();
 //テンプレートファイルの呼び出し
 $this->template->content=View::forge('collection/index');
 //データベースをテンプレートに渡す
 $this->template->content->set('query',$query->as_array());
 }
 }

7. それでは、ブラウザで確認してみます。尚、上記の22行目はSQL文を確認するためのコードですので、不必要になったら、コメントアウトするか削除して下さい。

8. 『愛』と『人』の両方を含むデータが表示されました。SQL文の検索条件は好みで変えて下さい。私は、タイトル名に『A』と『B』の両方を含むかあるいは、備考に『A』と『B』の両方を含んでいるデータという意味で作成しました。きちんとSQLが発行されているのが確認出来ます。

コードの解説

9. それでは複合語検索のコードの解説を致したいと思います。

  • preg_split(分割するためのパターン文字列,入力文字列)
    7行目のpret_split()は正規表現で文字列を分割し、分割した値を配列で返すPHP関数です。第1引数には、分割するための文字列を正規表現で記述し、第2引数に元になる入力文字列を記述します。今回の場合、POSTで受け取った値を正規表現の全角又は半角で分割して、分割した文字列を配列$keywordsに代入しました。
  • implode(連結文字列,連結したい文字列の配列)
    14行目のimplode()は、配列要素を文字列により連結するPHP関数です。PHPのマニュアルには、引数をどちらの順番でも受け付けることが可能となっていますが、推奨は、上記の順番です。

本日は以上です。

このエントリーを含むはてなブックマーク Buzzurlにブックマーク livedoorクリップ Yahoo!ブックマークに登録

トラックバック&コメント

この投稿のトラックバックURL:

コメントをどうぞ

このページの先頭へ