Laravel – クエリーパラメーター

概要

クエリーパラメーターは、フォームの送信時にGETメソッドを指定した時に送信されるパラメーター形式。

ルートパラメーターが直接URIの一部としてパラメーターの値を送るのに対して、クエリーパラメーターはパラメーターの名前と値をセットで送る。たとえば以下の様に。

http://www.my_bbs.com/search_post?user_id=10

このパラメーターをコントローラーで取得するには、以下の2通りの方法がある。

  • アクションの引数でRequestオブジェクトを指定し、その属性でパラメーター名を指定する。
  • アクション内でrequest()関数の引数にパラメーター名を指定する

いずれの場合も、コントローラーで以下の指定が必要。

use Illuminate\Http\Request;

ルーティング

ルーティング設定では、パラメーターを送信するパスとそれを受け取るコントローラー・アクションを指定するだけで、特別の記述はない。

Route::get('パス', 'ルーティング先');

たとえばmy_bbsというアプリケーションで以下のようにルーティングを設定した場合、

リクエスト側のURLは以下のようになる。

http://www.my_bbs.com/search_post?user_id=5

複数のパラメーターを送る場合は以下の様に'&'で区切る。

http://www.my_bbs.com/search_post?user_id=5&keyword=hello

ルーティングではパラメーターの数や名前には関与せず、コントローラー・アクションにおいてこれらを扱う。

コントローラー

必須事項

Request使用の宣言

コントローラー定義前に以下の定義が必要。artisanでコントローラーを生成すると、この定義は自動的に含まれる。

use Illuminate\Http\Request;

アクションの引数でのRequestオブジェクト指定

コントローラーでクエリーパラメーターを扱うのに、Requestパラメーターをアクションの引数に指定する方法と、request()関数を使う方法があるが、いずれの場合でも、アクションの引数にRequestクラスのオブジェクトを引数として指定する。

public function アクション名(Request $request) { ... }

引数の変数名は、必ずしも$requestでなくてもよい。

共通のコントローラー・アクションの形式

上記2つをまとめたコントローラー・アクションの一般形は以下のとおり。

アクションにおけるパラメーターの取得

Requestオブジェクトの属性からパラメーターを受け取る方法

アクションの引数に指定したオブジェクトの属性値に、パラメーター名を指定して値を取り出す。引数の変数名は$requestである必要はなく任意。

$request->パラメーター名

たとえば先のリクエストの項で挙げた例の場合、以下のような処理例となる。ビューではコントローラーで設定された変数を使う。

複数パラメーターが送られる場合は、Request引数の属性で順次パラメーター名を指定して取り出す。

request()関数にパラメーター名を指定して受け取る方法

request()関数の引数に、クエリーのパラメーター名を指定して値を取り出す。

request('パラメーター名');

上記の複数パラメーターの例をこの方法で書き換えると以下のとおり。

パラメーター省略時

リクエスト送信時にパラメーターを送信した時など、コントローラーで想定したパラメーターが存在しないときはエラーにならず、値が空文字列となる。

 

Laravel – ルートパラメーター

概要

ブラウザーなどからのリクエストの際、URLにパラメーターを指定して、それをLaravelで利用することができる。

クエリーパラメーター(URIパラメーター)と異なり、ルーティングのパスそのものにパラメーターを含める方法。

たとえば以下のようにリクエストでパラメーターとして'1'を送り、

ルーティングで以下のようにパラメーターを受け取り、

アクションで変数として受け取って利用する。

ルーティングでの設定

パラメーターを受信する場合、ルーティングでパラメーターの部分を{}で囲む。

Route::get('パス/{パラメーター}', 'ルーティング先');

これ呼び出すリクエスト側のパラメーター指定は以下の通り。

http://ホスト名/パス/パラメーター

たとえばmy_bbsというアプリケーションで以下のようにルーティングを設定した場合、

リクエスト側でid=3を送る場合ののURLは以下のようになる。

http://www.my_bbs.com/user/3

コントローラーでの受け取り方

ルートパラメーター付きでルーティングされたコントローラーのアクションでは、その引数にパラメーターを指定する。

先のルーティングのパラメーターを利用する場合、たとえば以下のようなコントローラー・アクションになる。

なお、ルーティングで指定したパラメーターの名前とアクションの引数に使う変数名は、必ずしも一致させなくてもよい。

デフォルトパラメーター

ルーティングでパラメーター設定を{パラメーター?}のように書き、アクションで引数のデフォルト値を指定すると、パラメーターが省略されたときのデフォルト値を設定できる。

ルーティングの例

アクションの例

この場合、http://www.my_bbs.com/userのようにパラメーターを指定しないと、id=0として処理される。

複数のパラメーター

ルートパラメーターは複数設定することもできる。

たとえば以下のように、ユーザーIDと投稿IDを想定してルーティングできる。

これを受け取るアクション側では、パラメーターの順番に合わせて引数を指定する。

この場合もパラメーターの名前と変数名は同じである必要はなく、その順番のみに従ってパラメーターの値が変数に割り当てられる。

なお複数パラメーターの場合のデフォルトパラメーターについては、最後のパラメーターには設定できるが、それより前のパラメーターには設定できない。

たとえばRequest::get(/user/{user_id?}/post/{post_id?}としてアクションの引数でそれぞれに対応する引数にデフォルト値を設定しても、

http:/www.my_bbs.com/usr/3/post

のように最後のパラメーターを省略するのは可能だが

http:/www.my_bbs.com/usr/post

のように全パラメーターを省略したり

http:/www.my_bbs.com/usr//post

途中のパラメーターを省略すると正しくリクエストできない。

 

Laravel – ルーティング

ルーティングの基本形

Route::メソッド('パス', ルーティング先);

たとえばGETメソッドで'ドメイン/bbs/show_posts'がリクエストされ、そのコントローラがBbsController、メソッドがshowPostsの場合は以下のように書く。

メソッド

HTTPメソッドに対応したRouteクラスのスタティックメソッドが準備されている。

  • get
  • post
  • put
  • patch
  • delete
  • options

URL

HTTPリクエストで指定されるURLを記述する。

  • ドメイン以下のパスを書く
  • 頭の'/'はあってもなくてもよい

たとえばGETメソッドによるhttp://www.my_site/bbs/show_postsへのリクエストを扱う場合は以下のようになる。

または

ルーティング先

コントローラーとアクションを指定

'コントローラー名@アクション名'で指定する。

たとえば上記のURLへのリクエストをBbsControllerコントローラーのshowPostsアクションにルーティングしたい場合は以下のように指定する。

シングルアクションコントローラーを指定

'コントローラー名'で指定する。

たとえば上記のURLへのリクエストでシングルアクションコントローラー'ShowPosts'にルーティングしたい場合は以下のように指定する。

直接ビューを指定

コントローラーを介さずに直接ビューを指定する方法。無名関数を使い、戻り値にビューを指定したview()関数を渡す。

Route::get('パス', function () { return view('ビュー'); });

たとえば先のURLへのリクエストでビューファイルが以下のように配置されているとする。

resources/views/bbs/profile.blade.php

この場合のルーティングは以下のようになる。

ビューで参照する変数がある場合、以下のようにコントローラーと同じように無名関数の中で設定できる。

直接出力

無名関数の戻り値に直接文字列を渡すと、それがそのまま送信される。

Route::get('パス', function () { return '文字列'; });

以下の例では、ブラウザーに単に「こんにちは」とだけ表示される。

直接HTMLを送ることも可能。

ルートパラメーター

ルートパラメーターは、以下の様にリクエストURIの一部としてパラメーターの値が送信される。

http://ドメイン/.../パラメーター

パラメーターの値のみ送り、それを扱う変数の名前はLaravelで指定する。

 

Larave- コントローラーの基礎

コントローラーの生成

artisanで作成する

php artisan make:controller コントローラー名

コントローラーが配置される場所。

app/Http/Controllers

初期状態のコントローラーの内容。

一般的な構成

ビューの基礎で使ったblade_sampleはルーティングファイルに変数などを記述して呼び出していた。しかし一般的には、ビューに必要な処理はコントローラーのメソッド=アクションを記述し、ルーティングではコントローラーのアクションを呼び出す、という方法が取られる。

そこで、このルーティングに書かれた処理をコントローラーに記述しなおし、ルーティングはコントローラーを呼び出すだけの構成に変更する。

コントローラーの記述

先に生成したSampleControllerクラスのメソッドとして、sampleAction()を定義し、その中に変数定義などの処理とビューの呼び出しを記述する。

ルーティングでのアクションの定義

ルーティングの無名関数で処理を記述していた部分を、アクション呼び出しの書き方に変更する。

このように変更することで、ルーティングはURLとメソッドをアクションに結びつけることに専念し、シンプルになる。

 

Laravel – レイアウト

概要

  • 複数のビューで共通の部分がある場合、それらをまとめたビューを作って親とする(レイアウト)
  • 共通レイアウトの中で、個々のビューごとに内容が異なる部分に@yieldディレクティブを書く
  • 個々のビューの最初で、レイアウトとして使うビューを@extendsで指定する
  • レイアウトの中で@yieldを書いた部分の具体の内容を@sectionディレクティブで書く
  • 異なるレイアウトでまとめられる部分がある場合は親のレイアウトにまとめて、異なる部分を親レイアウトの@yieldと子レイアウトの@sectionで書き、階層化する

レイアウトとビュー

レイアウトもビューファイルだが、複数のビューで共通化できる部分をまとめたのがレイアウト。

個別のページごとの内容に対応する部分を、レイアウト中で@yieldディレクティブで名前を付けて仮置きしておく。

たとえば以下は各ページ共通のヘッダーをレイアウトに持たせて、個別ページのタイトルと内容はtitlecontentという名前で仮置きしている。

個別のページでは、

  • レイアウトとして使うビューを@extendsディレクティブで指定する
  • レイアウト中@yieldで仮置きした部分に対応する内容を@sectionディレクトリーで具体に書いていく

この例では、全体のレイアウトとして上で準備したビューファイルを指定して、タイトルと内容を@sectionディレクティブで具体に書いている。

@sectionディレクティブには以下の書き方がある。

  • 2つ目の引数で内容を渡す方法
  • @section@endsectionの間に具体の内容を書く方法

レイアウトの階層化と継承

レイアウトが一部共通部分を持ちながら、いくつかの種類に分けられるような場合、レイアウトを階層化する。

例えばログイン前のページ、ログイン後のページが複数あり、ログイン前後でヘッダーメニューの構成が変わる場合。

ログイン前後でヘッダーメニューの内容は異なるが、ヘッダーメニューがあるという点は共通。

共通レイアウト

まず、大元のlayouts/common.blade.phpを以下のように準備する。

このレイアウトでは、タイトル、ヘッダー、内容の3つを@yieldでプレースホルダーとしている。

個別レイアウト

次に、ログイン前とログイン後それぞれのレイアウトを準備する。

全体構造は共通のcommonから@extendsで継承し、それぞれで異なる内容となる@yield('header')に対応する部分だけを具体に書いていく。

個々のページによって異なる@yield('title')@yield('content')についてはここでは対応せず、具体のビューで内容を埋める。

以下はログイン前のレイアウト。

また、以下はログイン後のレイアウト。

個別ビュー

個別のビューでは、大元の共通レイアウトを継承したログイン前/後いずれかのレイアウトを指定する。そして未対応@yield('title')@yield('content')に対応する内容を@sectionで埋めていく。

たとえばログイン前のログインページの例。

またログイン後のトップページの例は以下の通り。

 

Laravel – ビューの基礎

基本的なビューの表示方法

概要

routes/viewsディレクトリー下かそのサブディレクトリー下にビューファイルを置き、ルーティングでそれを指定する。

ビューファイル名には.blade.phpが付加され、HTML以外にLaravelの機能を持たせるための記述を含む、Bladeテンプレートとして扱われる。

  • ビューファイルは
    • resources/viewsディレクトリー下、あるいはそのサブディレクトリー下に置く
    • ファイル名は[ビュー名].blade.phpにする
  • ルーティングでビューファイルを指定するときは
    • 無名関数の処理内容をreturn view('ビュー名');とする
      • ビュー名はビューファイル名から.blade.phpを除いたもの
    • ビューファイルをサブディレクトリー下に配置した場合、resources/viewより下のパスを、デリミターを'.'として記述する

例1

Laravelプロジェクト生成直後に表示される”Laravel”の初期ページ。ルーティングファイルに以下だけ記述されている。

また、resource/viewsディレクトリーにはwelcome.blade.phpファイルのみ準備されている。

内容は以下のとおり。

例2

resourcesディレクトリーの下にsamplesディレクトリーをつくり、その中にview_sample.blade.phpというファイル名で以下の内容のファイルを作成する。

routes/web.phpファイルに以下のルーティングを追加する。

サーバーが起動している状態でブラウザーからドメイン/view_sampleにアクセスすると、view_sample.blade.phpがパースされて表示される。

この場合のビューファイルとview()メソッドでの指定の仕方は以下のとおり。

  • ビューファイルをviewsディレクトリーのサブディレクトリーsamples下に作成
    • views/samples/view_sample.blade.php
  • view()メソッドで呼び出すときは'.blade.php'を除き、パスのデリミターを'.'にした形で指定
    • samples.view_sample

URIの/view_sampleとファイル名のview_sample.blade.phpは必ずしも同じである必要はない。

変数の展開

概要

ビューファイル内に、PHPの変数を埋め込んで内容を反映させることができる。

  • ビューに対して変数を渡すときは、[変数名]=>[内容]を要素とする連想配列で渡す
  • ビュー側では、連想配列のキーが変数名、値が内容として解釈される
  • ビュー内で{{ 変数 }}とすると変数の内容が展開され、HTMLに埋め込まれる

resources/samplesディレクトリー下に、ファイル名blade_sample.blade.phpで以下の内容のファイルを作成する。

このビューに対して、routes/web.php内で以下の様にルーティングを設定。

ビューファイルのパース時に変数が展開され、内容がHTMLに埋め込まれるため、ブラウザーでの表示結果は以下のようなイメージになる。

bladeテンプレートでの変数展開
  • 連想配列をview()の第2引数に渡す
  • それを受け取ったビューでは、キーが変数名、値が変数の内容となる

出力エスケープ

変数埋め込みで内容を展開する際、HTML特殊文字はエンティティーに変換されるが、エスケープを抑制してHTML特殊文字をそのまま出力する方法もある。

概要

  • ビューで{{ ... }}とするとHTMLの特殊文字はLaravelによってエスケープされる
  • {!! ... !!}とするとHTMLの特殊文字はエスケープされず、HTMLとして機能する

ルーティングファイルweb.phpに以下の2行を追加する。

また、先に作成したビューファイルblade_sample.blade.phpに以下の2行を追加する。

この場合のブラウザーの表示結果は以下のイメージ。

bladeテンプレートでの変数展開
  • 連想配列をview()の第2引数に渡す
  • それを受け取ったビューでは、キーが変数名、値が変数の内容となる

HTML特殊文字は<strike>自動的に</strike>エスケープされる

{{…}}}ではなく{!!…!!}で囲むとエスケープされるされない

コメント

Bladeテンプレート内にコメントを書くことができ、HTMLへのパース時にはコメント行は無視される。

概要

  • Bladeテンプレートのコメントは{{-- ... --}}で記述する
  • Bladeのコメントはパース後のHTMLには現れない

最初に使ったview_sample.blade.phpファイルに以下の2行を追加する。

これがパースされた後のHTMLソースは以下の様になり、Blade用のコメントはソースに反映されていない。

ディレクティブ

概要

Bladeテンプレート内に条件分岐やループなどを行うディレクティブを書くことができる。

  • ディレクティブはBladeテンプレートに記述し、ロジック制御やレイアウト処理などPHPとしての処理を埋め込む
  • ディレクティブは@キーワード...のように記述する

まず、ルーティングでビューに配列を渡す。

ビューでは、配列の要素を一つずつ取り出して表示させている。

ここで使われている@foreach@endforeachがディレクティブで、ビューの中でPHPの処理・制御をしたり、レイアウトを扱ったりすることができる。

ディレクティブの詳細はこちら

レイアウト

レイアウトに関するディレクティブを使って、ファイルの共通のレイアウトをまとめることができる。

概要

  • 共通レイアウトのビューを親とする
    • プレースホルダーとして@yieldディレクティブを書く
    • @yieldごとにその場所に入るべきセクション名を指定
  • 共通レイアウトを利用するビューを子とする
    • 親とするレイアウトビューを@extendsディレクティブで指定する
    • 親の各@yieldに対応するセクションを@sectionディレクティブで定義し、その内容を記述する

共通のレイアウトとして、views/layouts/common.blade.phpを以下の内容で準備する。

  • titlle要素に'title'セクションの内容を反映
  • main要素に'content'セクションの内容を反映
  • header要素の部分は、このページが変わっても同じ内容が表示される

この共通レイアウトを使うページを、views/samples/layout_sample.blade.phpとして以下の内容で準備する。

  • @extendsディレクティブで、レイアウトとして使うビューを指定している
  • 1つ目の@sectionディレクティブでtitleセクションに反映させる内容を$title変数で与えている
  • 2つ目の@sectionディレクティブでcontentsセクションに反映させる内容を記述している

これらについて以下のルーティングを設定し、ブラウザーからアクセスする。

出力イメージは以下の様になる。

共通レイアウトに各ページ共通のヘッダーなどを置けます
bladeテンプレートでの変数展開

3は3の倍数
5は5の倍数
6は3の倍数
9は3の倍数
10は5の倍数

スタイル

概要

  • publicディレクトリー下、あるいはそのサブディレクトリー下にCSSファイルを配置する
  • linkタグでCSSファイルを指定する

publicディレクトリー以下に配置されたファイルをlinkタグで指定するには、以下の様に記述する。

たとえばpublicディレクトリー下にcssディレクトリーを作成し、その下にstayles.cssを作成、CSSを記述したとする。

このファイルをビューから呼び出すには、以下の様に記述する。

 

Larave – ディレクティブ

概要

ディレクティブ(directive)はBladeテンプレート内に記述し、テンプレート内でPHPの処理・制御をおこなったり、共通のレイアウトを扱うといった処理を指示する。

ディレクティブは@キーワードのように書き、そのキーワードに応じて必要な表現が続く。

ロジック制御系ディレクティブ

分岐系ディレクティブ

@if

@unless

@empty

@isset

ループ系ディレクティブ

@for

@foreach

@forelse…@empty

@while

@break

PHPのbreakと同じ使い方。

@continue

PHPのcontinueと同じ使い方。

$loop変数

$loop->index 現在のインデックス(0, 1, 2, …)
$loop->iteration 現在の繰り返し数(1, 2, 3, …)
$loop->remaining あと何回繰り返すか
$loop->count 配列の要素数
$loop->first 繰り返しの最初かどうか
$loop->last 繰り返しの最後かどうか
$loop->depth 繰り返しのネストの深さ
$loop->parent ネストしている場合の親のループ変数

共通化・再利用関係ディレクティブ

レイアウト関係ディレクティブ

レイアウト関係はこちらにまとめている。

@extends/@yields/@section

  • @extendsでレイアウトとして使う親のビューを指定
  • @yieldで個別ビューで埋めるべきプレースホルダーを指定
  • 個別ビューやサブレイアウトで@sectionを指定し、対応する@yieldを具体の内容で埋める

@show

@parent

部分HTML関係ディレクティブ

@include

@includeディレクティブは、別に準備された共通の部分ビューをその場所に読み込む。第2引数に連想配列を指定して、引数を渡すことができる。

例として、以下は共通して読み込まれる部分ビュー。

そして以下は、@includeで上のHTMLを読み込むビュー。

@component/@slot

@includeと同じように共通の部分ビューを読み込むが、変数を指定するのに連想配列で渡す方法と@slotディレクティブで指定する方法がある。

以下は@componentで読み込まれる部品側のファイル。

そして以下は、この部品を読み込んで使う親のファイル。

@each

@eachディレクティブは、配列やコレクションの内容を取り出しながら、その内容を繰り返してビューに適用していく。

ビュー2はコレクションが空のときに使われるビュー。

たとえば以下のような部分ビューを準備しておいて、

以下のように@eachを使うことで、配列の要素1つずつに同じ部分ビューの内容を適用させることができる。

この結果、@componentの時と同じようなリストが配列の要素に対応して作られる。

@import/@component/@eachの使い分け

これら3つを使い分けるシーンについて、以下のように考えてみた。

@import
ある程度の規模の定型部分ビューの一部を変数で与えながら再利用する場合。
@component
個別ビューでHTMLの一部を設定しながら一定の構造を持たせる場合。
@each
コレクションの内容に応じたリスト項目の表示など、部分HTMLに対して定型で内容が変化する場合。

 

Laravel – ルーティングの基礎

ルーティングファイル

  • Laravelのルーティングはルーティングファイルに書く
  • ルーティングファイルの場所はapp/routes/web.php

ルーティングの書き方

ビューの雛形

生成直後のルーティングファイルでは下記のルーティングのみが書かれており、準備されたビューファイルが返されるようになっている。

無名関数の中でview()メソッドが呼ばれているが、このメソッドの引数文字列に.blade.phpを付けたファイル名のビューファイルが、resources/viewsディレクトリー下で検索されて表示される。

直接出力

ブラウザーに文字列だけを表示する簡単な例として、GETで/topにルーティングして’ようこそ’と表示するには以下の様に書く。

Route::get('top', function() { return 'ようこそ'; });

get()メソッドの第1引数にURI、第2引数にそのURLにGETしたときに返されるコンテンツを指定している。

  • 第1引数のURIは、ドメイン以降のディレクトリー・ファイルで、冒頭の’/‘は付けても付けなくてもよい
  • 第2引数の無名関数は、コントローラーに渡されるコールバック

無名関数の戻り値に直接HTMLを書けば、その内容がブラウザーでパースされて表示される。つまり以下のような書き方もできる(現実的ではないが)。

リクエスト元の指定

第1引数はドメインより後のパスを指定する。たとえばリクエストが

http://www.myapp.com/user/profile

の場合は以下のようになる。

Request::get('/usr/profile', ...);

または

Request::get('usr/profile', ...);

コントローラー・アクション指定

コントローラーとアクションを指定する以下の書き方が一般的。

Route::get('パス', 'コントローラー名@アクション名');

 

Laravel – データベース – 準備

概要

Laravelのプロジェクト開始時の、データベースの準備・設定についてまとめる。

データベースの準備

CREATE DATABASEなどによってプロジェクトで使うデータベースを作成する。以下は新たなデータベースlaravel_test_developmentを作成した例。

.envファイルの修正

データベース接続確認

php artisan migrateでマイグレーションが実行されればデータベースは正常に接続されている。

マイグレーションの結果生成されたファイル。

MySQL側でもテーブルが生成されている。

データベースに接続できないとき

MySQLとPHPのバージョンによっては、認証方法の違いで接続できない場合がある。その対応方法はこちら

 

Laravel – データベースに接続できない

エラー発生

Laravel導入直後にデータベースを接続しようとしたところ、エラーが発生した。

MySQLのバージョンは8.0.23、PHPのバージョンは7.3.28で、MySQLのデフォルトの認証はcacing_sha2_passwordだが、PHPは7.3でもこれに対応しておらずmysql_native_passwordらしい。

MySQLの認証方法変更

認証方法の確認。

rootの認証方法をmysql_native_passwordに変更しようとするが、エラー。

パスワードがポリシーに適合していない。これは新たにMySQLをインストールした時にある状況。パスワード検証内容を確認してみる。

設定するパスワードに合わせてポリシーなどを変更。

改めてrootユーザーの認証方法を変更・確認。

これでPHP7.3以下で接続可能になる。