ここでは、Laravelでデータベースから投稿を取り出すために使う、データベース検索文(クエリ)の書き方を解説していきます。
サイトの投稿(記事)は、データベースに保存されます。なので表示するには、データベースから取り出す必要がありますよね。
→Laravelのデータベース(SQL)とは?初心者でもよく分かる図と例でやさしく解説。
じゃあ、どうやるのか?というと、コントローラーにクエリを書く事で、必要な投稿データを取り出す事ができます。
laravelでデータベースから取得。クエリの書き方(エロクワント版)
Laravelのクエリの書き方は以下の2種類があります。
- クエリビルダー
- エロクワント(モデル)
といってもほぼ書き方は一緒なんですが、Laravelを今後使いこなしていく場合、基本的にModelを併用するため、Eloquent版のクエリの書き方をここでは初心者向けに解説していきます。
→LaravelのModel(Eloquent)とは?初心者でも図とチュートリアルでちゃんと分かる!
Laravelでデータベースから情報を出すためのクエリの基礎的な書き方
では、初心者でもイメージしやすいように、例を出して説明します。
以下のような、投稿一覧ページを作りたいとします。
この投稿データ一覧は、データベースのformsテーブルに入ってるとします。
このformsテーブルは、Laravelのコントローラー上では、Formモデルを介して呼び出します。
Formモデルは、作成すると、appフォルダ内にForm.phpという名前で保存されます。
→LaravelのModel(Eloquent)とは?初心者でも図とチュートリアルでちゃんと分かる!
これをこのあとのコントローラーの記述で使います。
というわけで、コントローラーを開いて、投稿一覧を取得するためのクエリを書いていきます。
まず、useの所に、use App\Form;と書きます。appフォルダ内のForm.phpを使うって事です。
→Laravelのuseとは?超初心者向けにシンプルに分かりやすく解説
次にクエリを書くために、function indexを作りました。この中にクエリを書いていきます。
では、クエリの書き方ですが、まず、
Form::と書きます。
そして、ただ単にformsテーブルにある全投稿データを取り出したいなら、
Form::all();
これで取り出せます。
ただ、これの難点は、投稿の表示順を並べ替えたりができない点です。
例えば、投稿を新着順に並べたいなら、allを使わずに、
Form::orderBy('created_at', 'desc')->get();
と書きます。
orderBy が、並び替えるための命令です。( )部分は「created_atで降順(descending=新着順)に並べてください」という意味があります。
例えば、orderBy('title', 'asc')と書けば、「タイトルで昇順(ascending)となり、投稿があいうえお順に並ぶようになります。」
そして、クエリの最後には、基本的に
- ->get()
- ->first()
のどちらかを付けます。
get()は、検索の結果が複数ある場合は全部取得するという意味です。
first()は、検索の結果が複数あっても、最初に条件一致した1つだけを取得するという意味です。
なので、投稿一覧ページは複数の投稿があるので、get()を最後に付けます。
もし投稿の単独ページで1投稿しか表示しない時などは、first()を使います。
ちなみにget()を使うと、仮に100件の投稿を取り出したなら、100件が1ページに表示されちゃう。それを、1ページ10件にして、ページ送りを付ける方法もあるよ。
取り出したクエリはどうなっているのか?
$data = Form::orderBy('created_at', 'desc')->get();のように、取り出した投稿は、$data(変数)に保存されます。
じゃあ、この$dataにはどのようなデータが入ってるんでしょうか?
中はこんな感じになってます。
[
{"id":35,
"created_at":"2020-11-07 09:59:02",
"updated_at":"2020-11-07 09:59:02",
"title":"この花の名前を知ってますか?",
"main":"この花、庭に生えてたんですが、なんて花なんでしょう。知ってる方いらしたら教えてください。"},
{"id":34・・・}
]
そう、投稿データが連想配列(オブジェクト)という形になって入ってます。
なので、ブレード側で{{$data->title}}のように入力すると、titleの部分が表示されるというわけです。(実際は@foreachを使いますが)
取り出したクエリの中身を見る裏技
裏技というか、デバッグするための必須知識なんですが、
$dataの中に、この連想配列が入ってるわけですから、
その下にecho $data; と書いて、ブラウザでページを表示すると、
こんなふうに$dataの中身がサイトの上部に表示されます(日本語が文字化けしたりしますけど)。
より詳しくは→Laravelでクエリの結果を確認する方法。
取り出したいデータを限定するselect, where
では、今度は、一番クエリで使う命令であるselectとwhereを使ってみましょう。
先程は、formsテーブルの全カラムの情報を取得しました。
今度はデータベースから取り出すカラムを限定したいとします。
例えば、id, created_at, updated_at, title, main という5カラムのうち、titleだけを取得したいとします。
そういう時は、
Form::select('title')->orderBy('created_at', 'desc')->get();
のように書く事で、
[{"title":"この花の名前を知ってますか?"},{"title:"WYSIWYGエディタを使ってみた!"},{"title":"・・・"}]
のように、titleのみを取り出す事ができます。
そうだね、selectを使わなくても同じ表示はできるんだ。でも例えば、
- データが沢山ある場合は、取得データ量を減らして高速化できる
- 個人情報を取り出さない事で流出を防止する
- Javascriptに渡す時などは限定した方が扱いやすい
などの理由で限定する事が結構あるよ。特に個人情報が入ったテーブルから取得する時は、取り出すとコンソールの設定次第で中身が見えてしまう事があるから、そういう事故の防止も兼ねて、selectを使った方がいいね。
取り出したいデータに条件指定できるwhere
では、今度は、条件指定できるwhereを使ってみましょう。
例えば、URLが/2ならデータベースのid2番の記事を表示し、/5ならid5番の記事を表示するといった具合にしたいとしましょう。
この場合は、
Form::where('id', $id)->first();
と書きます。
仮に/show/4にアクセスがあった場合は、$idは4になり、
where('id', 4)というふうになった結果、idが4の投稿が検索されます↓
データベースのidが4の投稿が取り出されて、表示されるわけです。
これ以外にも、whereは様々な検索に対応できます。
例えば、このサイトのように、検索窓を作り、入力したワードが含まれる記事を探せるようにするとしましょう。
その場合は、
Form::where('title','like','%'.$keyword.'%')->get();
とする事で、入力したキーワードが前後一致するタイトルを検索してくれます。
例えば、検索ワード($keyword)が"りん"なら、
'%'.$keyword.'%' で、前後一致(タイトル:かりんとうを食べた)
'%'.$keyword で前方一致(タイトル:りんご狩りに行ってきた)
$keyword.'%' で後方一致(タイトル:カルシウムが足りん)
$keyword で完全一致(タイトル:りん)
のように'%'の付け方で検索にかかる条件を変えられます。
また、タイトルだけじゃなくて、本文からも同様に検索したい場合は、
Form::where('title','like','%'.$keyword.'%')->orWhere('main','like','%'.$keyword.'%')->get();
のようにすれば、タイトルか本文のどちらかに検索ワードが入ってれば、引っかかるようになります。
特に初心者がよく使う必須クエリを今回は紹介しました。
実際には他にも様々な条件を作る事ができます。
その他の命令については、公式サイトを見るといろいろありますよ。
今回のクエリを使ったチュートリアルもあるから、ぜひチャレンジしてみてね。