LoginSignup
14
13

More than 5 years have passed since last update.

Laravelでキーワード検索の配列を作成するミドルウェア

Last updated at Posted at 2019-03-10

はじめに

LaravelのミドルウェアはコントローラーにPOSTなどで送られてきたデータに対して、送る前に予め何らかの処理をさせることができる。

今回は、その性質を利用して、キーワード検索用に配列にする処理を作成する。

要件

キーワード検索フォームは、キーワード1 キーワード2というようにスペースで区切って検索対象にするワードを入力する使い方が多い。このため、単純にスペースで分割すればいいと考えがちだが、使う人は全角スペースも使うことを考慮しなければならない。

また、複数回スペースを入力されたり、同じキーワードが複数回入力されたときにそのままSQLパラメータとして使うのは非効率的である。

この手の処理は検索系ではどこでも使うので、通常は、共通のライブラリなどを参照するようにすることを考えるが、Laravelのミドルウェア機能を使って、透過的に使用することで、コントローラーのコードをすっきりさせることが可能である。

実際作ってみた

KeywordExploder.php
<?php
/**
 * キーワードを配列化
 *
 * @author    Logue <logue@hotmail.co.jp>
 * @copyright 2019 Logue
 * @license   MIT
 */

namespace App\Http\Middleware;

use Closure;

class KeywordExploder
{
    /**
     * キーワードを空白文字で分割し配列にする。
     *
     * @param \Illuminate\Http\Request $request
     * @param \Closure                 $next
     *
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $keyword = $request->input('keyword');
        $ret = [];

        if (!empty($keyword)){
            // +を半角スペースに変換(GETメソッド対策)
            $keyword = str_replace('+', ' ', $keyword);
            // 全角スペースを半角スペースに変換
            $keyword = str_replace(' ', ' ', $keyword);
            // %はSQL実行時にLIKEのパラメータとして使うのでスペースにする。
            $keyword = str_replace('%', ' ', $keyword);
            // 取得したキーワードのスペースの重複を除く。
            $keyword = preg_replace('/\s(?=\s)/', '', $keyword);
            // キーワード文字列の前後のスペースを削除する
            $keyword = trim($keyword);

            if (!empty($keyword) || $keyword !== '') {
                // 半角カナを全角カナへ変換
                $keyword = mb_convert_kana($keyword, 'KV');
                // 半角スペースで配列にし、重複は削除する
                $ret['keyword'] = array_unique(explode(' ', $keyword));
            }
        }

        $request->merge($ret);

        return $next($request);
    }
}

直訳するとキーワード発破者になってしまうが、これはexplode命令で配列にしているからであって深い意味はない。

使い方

ダウンロードしたKeywordExploder.phpapp/Http/Middleware内に置き、Kernel.php$routeMiddlewareに以下の行を追加。

'keyword' => \App\Http\Middleware\KeywordExploder::class,

次に、routes/web.phpの検索処理のルーティング部分に->middleware('keyword')と入れる。

あとは、コントローラーやモデル側のキーワード検索のSQLを発行する処理の部分で

$keywords = $request->input('keyword');
if(!empty($keywords)) {
    foreach ($keywords as $keyword) {
        $query->where('name','like','%'.$keyword.'%')
    }
}

みたいにforeachで回して使用する。

14
13
0

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
  3. You can use dark theme
What you can do with signing up
14
13