こんにちは!タクマです。
31歳未経験からエンジニア転職に成功し、
2021年3月より都内の受託開発企業にてWebエンジニアとして働いています。
今回はLaravelのキーワード検索機能の実装方法を解説します。
「ポートフォリオにキーワード検索機能を導入したい」
「キーワード検索機能の実装方法がわからない」
という方はこの記事を読めば、キーワード検索機能が実装できるようになりますので、ぜひ最後まで読んでください。
前提条件
- usersテーブルにnameカラムがあるものとする。
- ユーザー一覧ページに検索フォームがあり、そこでユーザー名検索ができるものとする。
- ユーザー一覧ページはルーティング、モデル、ビュー、コントローラの実装が完了しており、ユーザーの一覧が表示されているものとする。(
$users
という変数をforeach
で回して各ユーザーの名前が一覧で出ている状態)
Viewに検索フォームを追加
<form method="GET" action="{{ route('users.index') }}">
<input type="search" placeholder="ユーザー名を入力" name="search" value="@if (isset($search)) {{ $search }} @endif">
<div>
<button type="submit">検索</button>
<button>
<a href="{{ route('users.index') }}" class="text-white">
クリア
</a>
</button>
</div>
</form>
@foreach($users as $user)
<a href="{{ route('users.show', ['user_id' => $user->id]) }}">
{{ $user->name }}
</a>
@endforeach
<div>
// 下記のようにページネーターを記述するとページネートで次ページに遷移しても、検索結果を保持する
{{ $institutions->appends(request()->input())->links() }}
</div>
上記コードについて解説します。
まずフォームの送信先はユーザー一覧ページとします。
form
タグのvalue="@if (isset($search)) {{ $search }} @endif"
で検索した後に、検索した値をフォーム内に保持することができます。
($search
は後ほどコントローラーから渡される変数です)
クリアボタンは検索した値をクリアするボタンです。
コントローラーに検索機能に関するコードを追加
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
class UserController extends Controller
{
/**
* ユーザー一覧
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index(Request $request)
{
// ユーザー一覧をページネートで取得
$users = User::paginate(20);
// 検索フォームで入力された値を取得する
$search = $request->input('search');
// クエリビルダ
$query = User::query();
// もし検索フォームにキーワードが入力されたら
if ($search) {
// 全角スペースを半角に変換
$spaceConversion = mb_convert_kana($search, 's');
// 単語を半角スペースで区切り、配列にする(例:"山田 翔" → ["山田", "翔"])
$wordArraySearched = preg_split('/[\s,]+/', $spaceConversion, -1, PREG_SPLIT_NO_EMPTY);
// 単語をループで回し、ユーザーネームと部分一致するものがあれば、$queryとして保持される
foreach($wordArraySearched as $value) {
$query->where('name', 'like', '%'.$value.'%');
}
// 上記で取得した$queryをページネートにし、変数$usersに代入
$users = $query->paginate(20);
}
// ビューにusersとsearchを変数として渡す
return view('users.index')
->with([
'users' => $users,
'search' => $search,
]);
}
}
今回のキーワード検索は、複数ワードの部分一致に対応しています。
たとえば、下記のようなusersテーブルがあったとします。
id | name |
---|---|
1 | 高橋健太 |
2 | 山田翔太 |
3 | 佐藤信一 |
4 | 江藤裕太 |
5 | 山田浩二 |
「山田」と検索するとid2とid5が検索結果として返ってきますが、上記コードのように「山田 翔」と検索するとid2のみが結果として返ってくる、複数ワードの部分一致に対応した検索機能となっております。
その他コントローラの説明はコードの上のコメントを読んでください。
以上で検索機能の実装が完了です!
さいごに
いかがでしたでしょう?
キーワード検索機能が実装できましたでしょうか?
ご質問やご指摘等ある方はコメントしていただければ返信させていただきます。
これからもエンジニアの方、プログラミング初学者の方に役に立つ記事を更新していきますのでよろしくお願いします!
Twitterでも情報発信をしていますので、よかったらフォローをお願いします(^^)
タクマさん、初めまして!
今、Webエンジニアを目指して猛勉強中のものです。
いつもブログ拝見し、お世話になっております!!
本記事について、1点教えていただけないでしょうか?
【コントローラーに検索機能に関するコードを追加】で
$wordArraySearched = preg_split(‘/[\s,]+/’, $spaceConversion, -1, PREG_SPLIT_NO_EMPTY);
とありますが、preg_split(‘/[\s,]+/’, ~の『/[\s,]+/』部分は何を意味しているのでしょうか?
自身で調べてみても、どうしてもわからなかったのでご質問させていただきました。
またお時間ある時で大丈夫ですので、教えていただけないでしょうか?
よろしくお願い致します。
にくさん、初めまして!
ブログを読んでいただきありがとうございます。
いただいた質問に回答します。
『/[\s,]+/』は正規表現になります。
まず、正規表現は「/」と「/」で囲みます。
[ ]は[ ]の中の文字のいずれか一文字にマッチします。
『\s』は半角スペース、タブコード、改行文字を意味します。
『,』はそのまんまでカンマです。
『+』は直前の文字が1つ以上繰り返す場合にマッチします。
まとめると、『/[\s,]+/』は半角スペース、タブコード、改行文字、カンマが1つ以上続く場合にマッチします。
なので、
『,』⇦マッチする
『 』⇦マッチする
『, 』⇦マッチする
『,,』⇦マッチする
『a』⇦マッチしない
といった感じです。
正規表現がわからない場合は以下の記事とサイトがとても参考になりますでのぜひ読んでみてください。
参考1: https://qiita.com/jnchito/items/893c887fbf19e17d3ff9
参考2:https://www.megasoft.co.jp/mifes/seiki/meta.html
Webエンジニア目指して頑張ってください!
当ブログがにくさんの学習に少しでも役に立てば幸いです。
タクマさん
お返事大変遅くなり申し訳ございません。
とてもご丁寧な解説ありがとうございます!
正規表現は自身かなり苦手な部分であったので、思い切って質問してみてよかった!!と思っております。
ありがとうございました!
また今後ともタクマさんのブログをぜひ参考にさせてください!
よろしくお願い致します。
本件はありがとうございました!!!