MENU

Laravelについて

目次

環境構築

dockerを利用する

Docker
Docker: Accelerated Container Application Development Docker is a platform designed to help developers build, share, and run container applications. We handle the tedious setup, so you can focus on the code.
https://www.docker.com/

docker you are not allowedというエラーが表示されたら

管理者としてコマンドプロンプトを起動して、下記のコードを実行する
※windows 10 homeの場合

net localgroup docker-users "your-user-id" /ADD

※「your-user-id」の部分は、使用しているパソコンユーザー名

ターミナルで、docker is not runnigと表示されたら

①まずは、docker-desctopが起動しているか確認する

②docker-desctopが起動しているのに表示されている場合は、wslのバージョンを確認する
※wsl(Windows Subsystem for Linux)は、Windows上でLinuxを動作させるための実行環境のこと

dockerを利用する場合は、wslのバージョンが2である必要がある。
下記のコマンドでバージョン確認が可能

wsl -l -v
VERSIONが「1」の場合、変換する必要がある

バージョンを上げるためのコマンド

wsl --set-version Ubuntu-22.04 2

最後に、wslのデフォルトバージョンも変更

wsl --set-default-version 2

Composerについて

PHPのライブラリ管理ツールのこと。
ライブラリAを使用するためには、別のライブラリBを先にインストールする必要がある、なんてことがあります。
この時、ライブラリAはライブラリBに依存している、と言います。
Composerを使用することで依存関係にあるライブラリをまとめてインストールすることができます。

Composerを利用した環境構築

laravelプロジェクトを作成したいディレクトリでターミナルを起動して、
下記のコマンドを実行する。
※「プロジェクト名」のディレクトリも自動的に作成される。

composer create-project --prefer-dist laravel/laravel プロジェクト名

Laravelの初期設定

タイムゾーンの変更

config > app.php

'timezone' => 'UTC',
↓
'timezone' => 'Asia/Tokyo',

config > app.php

言語の変更

'locale' => 'en',
↓
'locale' => 'ja',

エラーについて

下記のコマンドを実行する事で、各種エラーページのテンプレートが一括で作成できる。

php artisan vendor:publish --tag=laravel-errors

エラーメッセージの日本語化

laravelの初期値は英語のため、日本語のパッケージを作成する必要がある。
日本語化する際の手順は下記の通り

  1. langディレクトリの作成
  2. 日本語パッケージの取得
  3. 必要に応じて改修

①langディレクトリの作成

プロジェクトディレクトリ直下に「lang」ディレクトリを作成する。

②日本語パッケージの取得

githubから有志の方が作成してくれてパッケージをダウンロード
※laravel10の場合、「10.xx」の最新版をダウンロード

ダウンロードしたファイル内にある「locales」ファイル内の「ja」のフォルダをコピーして、
作成したlangディレクトリ直下にコピーする。

https://github.com/Laravel-Lang/lang/tree/10.9.5

バージョンを変更する時は、緑マーカーのところをクリックして「Tags」から任意のバージョンを選択

③必要に応じて改修

自作のキー(フォーム内で定義したname属性)に関しては、
対応した日本語が存在しないため、下記のファイルに追加で定義を加える。

/lang/ja/validation.php

/lang/ja/validation.phpファイル内の最後に追記

    'attributes' => [
        '追加キー1' => '置き換える日本語1',
        '追加キー2' => '置き換える日本語2',
    ],
例:form内で名前フィールドに「name」というキーを設定したので、「name=名前」という定義を追加する。定義を追加する際は、元々ある配列の中に追記する(赤線が引いてある閉じカッコの中に追記)

Routing(ルーティング)

ルーティングとは

ルーティングを使用する事によって、ドキュメントルート外のファイルについてもブラウザからアクセスする事ができるようになる。
これにより、URLはファイル名にいぞんしないため、ディレクトリ名や構成を変更してもURLの変更が発生しない。
また、同じURLでも「GET」や「POST」などの条件によってかき分ける事が可能。

ルートの登録

web.phpにパスとHTTPメソッドの組み合わせに対応した処理を定義する


Route::HTTPリクエストメソッド(‘パス’,function(){処理内容})

routes > web.php
「/hello-world」にアクセスすると、「hello world」と表示される。
※①②どちらも出力結果は同じ

①
Route::get(
    '/hello-world',
    function (){
        return 'hello world';
    }
);

②PHP7.4から追加されたアロー関数を使って記述
Route::get(
    '/hello-world',
    fn() => 'hello world' //基本的に戻り値の部分は一行しか書く事ができない
);

View(ビュー)

ビューとは

HTMLなどブラウザでの表示内容が書かれたファイルのこと。
ルーティングからviewを使用してhtmlが記載されているbladeファイルを呼び出す事でHtmlとlaravelの機能を組み合わせたページを作成する事ができる。

Blade(ブレード)とは

/resources/views」配下に、「○○.blade.php」というファイル形式で作成。
中身は普通のHTMLの記述でOK。
またブレードテンプレート内では、laravelの変数も使用可能。

使用方法

ルートの登録でview関数を使用して、ビューファイル名を指定する。
※指定するビューファイル名からは「.blade.php」は省略してOK。
 下記のコードの場合、「/resources/view/hellow_world.blade.php」ファイルを
 viewで呼び出しているが、「hellow_world」の記述だけで良い

※「/resources/view/」配下にサブディレクトリを持たせる事も可能。
 その場合、「/」ではなく、「.(ドット)」で指定する。
 例:/resources/view/sub/test.blade.phpなら、
   → 「view(‘sub.test.blade.php’)」になる。

第2引数に連想配列を指定するとキーを変数名とするビュー内で使える変数が定義される。
テンプレート内で、変数や式などのPHPの内容を出力する場合は、下記の記述で行う。

{{$変数名}}

上記の記述で呼び出す事で、セキュリティ対応のためのHTMLエスケープ処理も行われている
※XSS(クロスサイトスクリプティング)対策

routes > web.php

Route::get(
    '/hellow_world',
    function (){
        return view(
            'hellow_world',
            [
                'name'=>'山田',
                'course'=>'laravel',
            ]
        );
    }
);
resources > view > hellow_world.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>
        Hellow world
    </h1>
    <p>こんにちは{{$name}}さん。</p>
    <p>こんにちは{{$course}}さん。</p>
</body>
</html>

bladeファイルを使用したテンプレート

  1. 共通部分をまとめたレイアウト用のbladeファイルを作成
    「views」配下に「layouts」ディレクトリを作成して、そこに共通のbladeファイルを作成
  2. ページごとに書き換える部分の設定
    @yieldディレクティブを使ってテンプレート外から指定を出来るセクションを設定します
  3. 個別ページの作成とレイアウト指定
    @extendsディレクティブを使って②で作ったレイアウトを指定します
  4. セクションの穴埋め
    @sectionディレクティブを使ってレイアウトファイルで設定したセクション部分を埋めていきます
views > layouts > default.blede.php
※headerやfooterを含んだ共通のテンプレート

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>@yield('title')</title>
</head>
<body>
    <header>
        <h1>Laravel9学習</h1>
    </header>

    <main>
        <h2>@yield('title')</h2>
        @yield('content')
    </main>

    <footer>
        <p>&copy; 2023 ●●▲▲</p>
    </footer>
</body>
</html>
views > index.bleade.php
※個別ページの内容(ルート登録して個別ページとしてブラウザに出力するページ)

@extends('layouts.default')

@section('title')
    さあ、はじめよう
@endsection

@section('content')
<p>
    Laravelの学習をはじめての方をサポートする学習サイトです<br>
    このサイトでは、Laravelの基礎だけでなく開発環境構築やデータベースに関しても解説します<br>
    これから学習を始めるににあたり、まずは下記の内容をご確認下さい<br>
    ~~~~ 以下省略 ~~~~
</p>
@endsection

変数や計算結果の出力

「{{$変数}}」で記述することでセキュリティ対応のためのHTMLエスケープ処理も行われている
※XSS(クロスサイトスクリプティング)対策

コメントアウト

下記のコメントアウトはDOMに表示されない

{{-- コメントアウト --}}

通常のPHPコードを使用したい場合

通常のPHPコードを埋め込む場合は、 <?php?>の代わりに @php と @endphpで処理をはさみます

@php
    $name2 = 'ララベル太郎';
@endphp

条件分岐

通常のPHPのif文に対応した@if、 @elseif, @else, @endif ディレクティブが用意されています
※符号の判定はphpと同じ。「==」なら値の比較、「===」ならデータ型を含めた値の比較

@if (条件式)
// 条件が真の場合の処理
@endif

繰り返し処理

通常のPHPの各繰り返し文に対応した@while, @for、 @foreach に加え@forelse ディレクティブも用意されています

@forelse ($users as $user)
    <p>{{ $user->name }}</p>
@empty
    <p>ユーザーが存在しない</p>
@endforelse

通常のPHPと同様に@continue および@breakディレクティブを使用して、 ループを終了 スキップすることもできます。
また、 $loop 変数がループ内で利用可能になります。

$users = ['name' => 'taro', 'age' => '30', 'tel' => '090-0000-0000'];

@foreach($users as $key => $val)
    @if($loop->first)
        初回のみ実行。ループで回る回数は{{$loop->count}}回です。
    @endif
    <p>
        現在のインデックス数【{{$loop->index}}】
        {{$key}} : {{$val}}
    </p>
    @if($loop->last)
        最後だけ実行。{{$loop->count}}回実行したので終了
    @endif
@endforeach

条件クラス

CSSのクラスを条件付きで出力するために、 @classディレクティブが用意されています
このディレクティブはクラス名の配列を受け取り、キーには出力したいクラス名、値はboolean型 (true/false) を設定します。
booleanがtrueの時のみ、クラスが出力されます。
※配列のキーを省略した場合は、 常に出力されます

Controller(コントローラー)とは

ルーディングから処理内容を分割させて、処理内容のみが書かれたファイルの事。
※基本、ルーティングにURLやそのページにアクセスした時の処理をセットで書くため、全てをルーディングファイルに記述していくと、記述量が膨大になってしまう。

コントローラーを作成するコマンドは下記の通り

php artisan make:controller コントローラー名
※コントローラー名はパスカルケースで指定(先頭も含め単語ごとに頭文字を大文字にする)
 例:GameController
※コマンド実行後は「app/Http/Controllers」にファイルが作成される

ルーティングから作成したコントローラーを読み込む方法は、下記のいずれか。
・nameスペースを含めた指定
・useを使ったインポート指定


例 読み込むコントローラー:App\Http\Controllers\GameController.php

nameスペースを含めた指定

Route::get('/omikuji',[
    App\Http\Controllers\GameController::class,
    'omikuji'
]);
useを使ったインポート指定

use App\Http\Controllers\GameController; //ページ上部に記載。記載の順番は問わない

Route::get('/omikuji', [
    GameController::class,
    'omikuji'
]);

Requests(送信されたデータの処理)

フォームなどから送信したデータの取得方法

フォームなどから送信されたデータはアクションの引数にRequestとタイプヒントをした変数に自動的にセットされます。
その変数に対し、 HTMLで指定したパラメータ名のプロパティで値を取得できます

hasメソッド

指定したパラメータが送信されているかを確認
例:「keyword」というパラメータ送られていたら

$keyword=未設定';
if ($request->has ('keyword')) {
    $keyword = $request->keyword;
}

getメソッド

Requestインスタンスのgetメソッドを使用すると、パラメータの送信確認及び、初期値の設定が簡単にできる。
※下記のgetメソッドを使えば、上記のhasメソッドを使用した時と同じ結果になる。

※getメソッドでのチェックはパラメータが送られているかどうかのチェック。
 パラーメータの値が、空かどうかのチェックではない(値が空でもパラーメータが存在していればtrue)

$keyword= $request->get ('keyword', '未設定');

ルートパラメータとは

URLクエリパラメータではなくURLのパスの一部分を同様に送信データとみなす機能。

複数のルートパラメータを使用する場合

Route::get('/products/{category}/{year}',
 function (Request $request, $category, $year) {
    return 'category: $category. '<br>'. $year. <br> page: $request->get('page', 1);
});

※ルートパラメータは指定順で利用可能になる(パラメータ名は関係ない)
 上記のコードであれば、「$category」「$year」の順番で利用可能。
 Requestと併用する場合は、Requestを先に記述する(Requestを記載する個所に縛りはない)

名前付きルート

命名したルート名を指定することでURLの呼び出しが可能になる。
つまり、コントローラーやビューの中でURLを呼び出す時に、フルパスを書く必要がなくなる。
ルート名を指定することでURLを呼び出すことができます。
※ルート名は一意である必要があります

また、パスの変更があったとしても、変更箇所はルート定義ファイルのweb.phpのみで済む。
※パスが変わっても、呼び出すルート名には変更が無いので他ファイルに変更の必要はない。

web.php

// ルート名の書き方
Route::get('/home', [HomeController::class, 'index'])->name('home');
Route::post('/user/{id}/profile', [UserProfileController::class, 'create'])->name('profile.create');
Controllerで名前付きルートの呼び出し

// URLの生成
$url = route('home');
Viewで名前付きルートの呼び出し

// formでのルート指定
<form method="post" action="{{ route('profile.create', ['id' => 1]) }}">

セキュリティ対策

getメソッド以外で送信する場合、セキュリティ対策のためCSRFトークンも送信が必要
CSRFトークンを送信するには@csrfディレクティブをformタグ内に設定する。

<form action="{{ route('login') }}" method="POST">
    @csrf
    <div><label>メールアドレス: <input type="email" name="email"></label></div>
    <div><label>パスワード: <input type="password" name="password"></label></div>
    <button type="submit">ログイン</button>
</form>

HTTPリクエストメソッド

HTTPリクエストメソッドは用途に応じて細かく用意されている。
※基本的には、「GET」と「POST」で対応可能だが、

GETデータの取得 (通常のリンク遷移もこれ)
※URLを直接指定したり、Aタグでの遷移もサーバーからHTMLデータを取得している
POSTデータの新規登録
GETで対応できないもの
秘匿性のあるもの
 GETメソッドはURLにパラメータを持ってしまうので、
 リファラなどに残る可能性があり第三者に取得されてしまう危険がある
データ容量の大きいもの
 GETのクエリとして渡せるのは最大2000文字程度
PUTデータの上書き
PATCHデータの部分更新
DELETEデータの削除

GET/POSTメソッド以外のフォーム

HTMLのフォームではGETとPOSTしかサポートされていないため追加設定が必要。
formタグのmethod属性にDELETEなどのメソッドを設定しても正しく動きません
Laravel では @methodディレクティブを使うことにより、これらのHTTPリクエストメソッドを擬似的に対応出来ます。

<form action="{{ route('users.destroy', ['id' => 1]) }}" method="POST">
    @csrf
    @method("DELETE')
    <buttun type="submit">削除</buttun>
</form>

HTTPリクエストメソッド別ルート登録

HTTPリクエストメソッドに対応するRouteクラスには各メソッドが用意されている。

リソースルート

典型的なルート登録を一括で行う事ができる。
よくあるルート登録の例として、1つのコンテンツに対し下記の7つが必要になることが非常に多いです。

  • 一覧表示用
    – index
  • 詳細表示用
    – show
  • 登錄フォーム表示用
    – create
  • 登錄処理用
    – store
  • 更新フォーム表示用
    – edit
  • 更新处理用
    – update
  • 削除処理用
    – destory

resourceメソッドを使いこれら7つのルートの登録を省略することが可能です。

Route::resource(‘/events’, EventController::class);
※「resource」メソッドを使用する場合、コントローラーの指定は配列([])にしない


Route::resource('/events', EventController::class);

7ルート全ては必要無い場合、
指定したものだけを設定するonly
・指定したものだけを除外するexcept
を使用する。

リソースコントローラーの作成

典型的なアクションが書かれたコントローラーの作成

php artisan make:controller EventController -r

リダイレクトについて

ブラウザに対して指定したページにアクセスするよう指示する機能
※リダイレクトされたページは、通常のアクセス同様にGETメソッドになる

Laravel9以降であれば、「to_route(‘ルート名’)」を使う記述が良い。

POSTメソッドを実行した後のリダイレクト

POSTメソッドを実行したページで、ユーザーが再読み込みを行うと
二重で処理が走る可能性があるため、POSTメソッド実行後は必ずGETメソッドのページにリダイレクトさせるようにする。

デバッグ・ログ用関数

変数の中身などを確認、処理履歴を保存できる関数のこと

デバッグ

多次元配列なども見やすく整形して出力

dump(出力したい変数など)

ログ

ページ内ではなく、ファイルに出力
ログ関数を使用する場合は下記ファイルの読み込みが必要になる。

use Illuminate\Support\Facades\Log;

デフォルトでは、「/storege/log/larvel.log」に書き込まれる。

use Illuminate\Support\Facades\Log;

Log::debug(出力したい変数など)

Session(セッション)について

複数のページ間をまたいでも受け渡しできるデータの管理方法。
データを書き換えられては困るようなデータに関しては、
getやpostで取得するのではなくsessionに保存して渡す。

※セッションに保存したデータはサーバー側に保存される
※ユーザーに隠したい値を「type=”hideen”」で仕込んでおいたとしても、ディベロッパーツール等でソースを書き換えることはできるため、書き換えられると困るデータはsessionで渡す。

セッションの取得

単純にデータの取得

$val = session('key')

データの取得かつ、存在しない場合はデフォルト値の設定

$val = session('key','default値')

全セッションデータの取得

$data = session()->all();

セッションにデータ保存

データの保存は連想配列で渡す

session(['key' => 'value'])

セッションの存在判定

null以外の値が設定されているか

if(session()->had('users')) {
    //ユーザー情報が存在する、かつ、nullではない場合の処理
}

値がnull以外、かつ、値が空では無い時の条件文は、

if(session()->had('users') && !empty(session('users')) ) {
    //ユーザー情報が存在する、かつ、nullではない場合の処理
}

キーが存在するかどうか(値がnullだろうが空だろうが関係ない)

if(session()->exists('users')) {
    //ユーザーというキーが存在する時の処理
}

キーの操作

一つのキーを削除

session()->forget('name');

複数のキーを削除

session()->forget(['name', 'status']);

取得と削除を同時に行う

この操作はセッションから値を一度だけ取得して取り出す時に使う。
※下記の場合、「key」というデータがあれば、それを$valに入れるし、なければ「default」という値を入れる。
その際、セッションから「key」とその値を削除する。

$val = session()->pull('key', 'default');

フラッシュメッセージとは

次のリクエストまでの間だけ有効なセッション(データの一時的な保存)
※保存されたデータは、次のリクエスト時に自動削除されるため以降は使用できません

フラッシュメッセージに保存されえたデータは通常のセッションと同様の方法で取得可能。

session()->flash('キー',値)

フラッシュメッセージの使いどころ

操作の成功や失敗の通知:ユーザーの操作が成功したか、失敗したかをユーザーに伝えるために使用されます。たとえば、フォームの送信が成功した場合に「保存しました」といった成功メッセージを表示することで、ユーザーに操作の成功をフィードバックすることができます。逆に、フォームの送信が失敗した場合にはエラーメッセージを表示することで、ユーザーにエラーの内容や修正が必要な項目を伝えることができます。
ページリロードによる重複操作の防止:フォームの送信などの処理後にリダイレクトを行い、フラッシュメッセージを表示することで、ユーザーがページをリロードすることによる重複操作を防止することができます。フォームの送信後に直接リロードすると、同じデータが重複して作成される可能性がありますが、リダイレクトとフラッシュメッセージの組み合わせにより、ユーザーに対して重複操作の警告を提供することができます。
ユーザーエクスペリエンスの向上:ユーザーに対して操作の結果や状態を明確に伝えることで、ユーザーエクスペリエンスを向上させることができます。操作の成功やエラーメッセージ、重要な情報の提示など、ユーザーが必要な情報を適切なタイミングで提供することで、ユーザーがアプリケーションをより使いやすく、快適に利用できるようになります。
// session ('success', 'お問い合わせありがとうございました');
session()->flash('success', 'お問い合わせありがとうございました)

// リダイレクト系のメソッドにwithメソッドをつなげて書いても同義です
return to_route('home')->with('success', 'お問い合わせありがとうございました');

セッションが存在するかどうかを確認して、
「値があれば表示」とするのであれば、
ifディレクティブhasメソッドを組み合わせる。

controller.php

public function store(Request $request)
{
    $title = $request->get('title');
    return to_route('events.create')->with('success',$title.'を登録しました。'); //リダイレクトにフラッシュメッセージのセッションを持たせる
}
blade.php

@if (session()->has('success')) //指定したセッションが存在していれば
    <p>
        {{ session('success') }}
    </p>
@endif

validation(バリデーション)

フォームから送信された内容を検証するには、Requestインスタンスのvalidateメソッドを使用する。
引数は、フォームのパラメーター名をキーとする連想配列で、値には配列でルールを指定する。
※ルールは複数設定することも可能

戻り値は、バリデーション済みデータの連想配列になる。
一つでもエラーがあった場合は後続の処理は行われず、入力画面に自動でリダイレクトされる。
※上記の①②はどちらも同じ処理になる。

①「,」区切り
$validatedData = $request->validate([
    'パラメータ名' => [ルール1', 'ルール 2'],
    'パラメータ名2' => [ルール1', 'ルール 2'],
]);

②「|」区切り
$validatedData = $request->validate([
    'パラメータ名' => [ルール1'|'ルール 2'],
    'パラメータ名2' => [ルール1'|'ルール 2'],
]);

// バリデーションが成功した場合の処理
// $validatedData にはバリデーション済みのデータが含まれる

代表的なバリデーションルール

バリデーションルール説明使用例
required必須入力チェック‘name’ => ‘required’
nullableフィールドが存在しても空であることを許可‘middle_name’ => ‘nullable’
numeric数値であることをチェック‘age’ => ‘numeric’
integer整数であることをチェック‘count’ => ‘integer’
boolean真偽値であることをチェック‘is_admin’ => ‘boolean’
string文字列であることをチェック‘name’ => ‘string’
email有効なメールアドレスであることをチェック‘email’ => ‘email’
alphaアルファベットのみで構成されていることをチェック‘username’ => ‘alpha’
alpha_numアルファベットと数字のみで構成されていることをチェック‘password’ => ‘alpha_num’
alpha_dashアルファベット、数字、ダッシュ、アンダースコアのみで構成されていることをチェック‘slug’ => ‘alpha_dash’
size:value値が特定のサイズであることをチェック‘file’ => ‘size:100’
min:value値が特定の最小値以上であることをチェック‘age’ => ‘min:18’
max:value値が特定の最大値以下であることをチェック‘quantity’ => ‘max:10’
between:min,max値が特定の範囲内にあることをチェック‘rating’ => ‘between:1,5’
regex:pattern正規表現パターンに一致することをチェック‘code’ => ‘regex:/^[A-Z]{2}\d{2}$/i’
date有効な日付形式であることをチェック‘birthday’ => ‘date’

バリデーションでエラーがあった場合

バリデーションエラーにより自動でリダイレクトされる場合
エラー内容が設定された$errorsという変数が自動的に定義され、 ビュー内で使えるようになる。

$errors->any()エラー確認boolean (一つでもあればtrue)
$errors->all()すべてのエラーを取得array
$errors->has(‘キー’)指定フィールド(キー)のエラー確認boolean (一つでもあればtrue)
$errors->first(‘キー’)指定フィールド(キー)の最初のエラーメッセージ取得string
Serrors->get(キー)指定フィールド(キー)の全エラーメッセージ取得array

エラーをまとめて表示する場合

@if($errors->any()) //エラーがあれば(エラーがあった場合、自動で$errorsは定義される)
    <div>
        <p>入力エラーがあります</p>
        <ul>
            @foreach($errors->all() as $error) //foreachで全て回す
            <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

個別にエラーを表示させる場合(@errorディレクティブ)

@errorディレクティブ内ではその項目(キー)の最初のエラーメッセージが設定された $message変数が利用できます。
※ifディレクティブとhasメソッドを使用して同様の事もできるが、@errorディレクティブを利用した方が楽

<div>
    <label><input type="text" name="last_name" class="@error("last_name') is-invalid @enderror"></label>
    @error("last_name")
        <p class="error">{{ $message }}</p>
    @enderror
</div>

入力内容の再取得

バリデーションエラーにより自動でリダイレクトされる場合、
$errorsの定義と合わせてフォームの入力内容がフラッシュメッセージとして自動的に保存されます。
この内容はold関数を使い簡単に取得でき、 フォームが再表示されたときに保存された直前の入力内容を設定出来ます。
※第2引数に未送信の場合の初期値を任意で指定することもできます

<input type="text" name="last_name" value="{{ old ("last_name')}}">

フォームリクエスト

バリデーションだけをフォームリクエストという別ファイルに分割することが可能。
これによりコントローラでは、正しい入力データが送信された前提でメインの処理に集中して記述出来ます
※登録と更新などバリデーションルールが同じ場合は共通化して使う事も出来るようになる

フォームリクエスト作成コマンド

php artisan make:request フォームリクエスト名

※フォームリクエスト名はパスカルケースで指定します(先頭も含め単語ごとに頭文字を大文字、他は小文字)

「認可」について

フォームリクエストには最低限、「認可」「ルール」を設定する必要がある。

認可とは入力内容ではなく当該ユーザが登録や更新などをすることを許可されているかの権限チェックのこと。
authorizeメソッドの戻り値に認可する場合はtrue、そうでない場合はfalseを設定します。
※ユーザー毎に実行できる内容を制御する必要が無い(誰でも実行可能)のであれば、常に「true」

public function authorize()
{
    return true;
}

「ルール」について

バリデーションで設定していたルールをそのまま設定する。

public function rules(): array
{
    return [
        'name' => ['required', 'string', 'max:255'],
        'name_kana' => ['required', 'string', 'max:255', 'regex:/^[ァ-ロワンヴー]*$/u'],
        'phone' => ['nullable', 'regex:/^0(\d-?\d{4}|\d{2}-?\d{3}|\d{3}-?\d{2}|\d{4}-?\d|\d0-?\d{4})-?\d{4}$/'],
        'email' => ['required', 'email'],
        'body' => ['required', 'string', 'max:2000'],
    ];
}

フォームリクエストの使用方法

アクションの引数にフォームリクエストのタイプヒントを入れる。
バリデーションで検証済みの内容は、「validated()」で取得可能。
※コントローラー等で作成したフォームリクエストを使用する場合は、「use ~」で読み込むのを忘れない。

use App\Http\Requests\ContactRequest;

public function sendMail(ContactRequest $request) {
    $validated = $request->validated();

    // これ以降の行は入力エラーがなかった場合のみ実行されます
    return to_route('contact.complete');
}

※上記は、「ContactRequest」というフォームリクエストを作成した場合の記述

フォームリクエストの任意設定

フォームリクエストごとに個別に属性名やエラーメッセージを設定が可能
属性名は attributesメソッド、 エラーメッセージはmessagesメソッドの戻り値に設定します。

attributesメソッド

フォーム内で設定したキー(name属性)の置き換えを設定できる。
「/lang/ja/attribute.php」内でattributesを設定しているキーを個別で上書きする事ができる。
※attribute.phpでは汎用的な設定値にしておき、個別のフォームリクエスト内で最適化させるとよい。

messagesメソッド

@errorディレクティブのmessageで表示される内容を置き換える事ができる。
記述方法は下記の通り。
例:

‘キー.regex‘ => ‘:attributeが正しくありません。’
※「:attibute」の部分は、attributesで設定した値が入る。(下記の場合であれば「お問い合わせ内容」

//フォームリクエスト内

public function attributes()
{
    return [
        'body' => 'お問い合わせ内容',
    ];
}

public function messages()
{
    return [
        'body.regex' => ':attributeが正しくありません。',
    ];
}

メールの設定

laravelでのメール送信は大まかには下記の流れ

  1. Mailableクラス (メールの情報をまとめたファイル)の作成
  2. メールの本文の設定
  3. 送信先を設定して送信

①Mailableクラス (メールの情報をまとめたファイル)の作成

Mailableクラスを作成する際のコマンド

php artisan make:mail Mailableクラス名

上記のコマンドを実行すると、/app/Mail ディレクトリに作成したMailableクラスが作成される。
予め作成されている envelope および content メソッド内で次の項目を指定します。

設定箇所(メソッド)引数名用途補足
envelopefrom差出人アドレス
差出人名(省略可)
サイト全体で同じものを一括設定する場合は
.envファイルのMAIL_FROM_ADDRESSと

MAIL_FROM_NAMEで設定
envelopesubject件名
contentview(または
html でも可)
ビューファイル名HTMLメールを送信する場合に指定する
textメソッドと併用可能
contenttextビューファイル名テキストメールを送信する場合に指定する,
viewメソッドと併用可能
public function envelope(): Envelope
{
    return new Envelope(
        from: 'no-reply@test.com',
        subject: 'Contact Admin Mail',
    );
}

public function content(): Content
{
    return new Content(
        view: 'view.name',
        text: 'text.name',
    );
}

差出人名も指定したい場合

fromにAddressクラスのインスタンスを指定する必要がある。
※Addressクラスを使用する場合は、下記のインポートが必要
use Illuminate\Mail\Mailables\Address;

new Address(‘差出人アドレス’, ‘差出人名’)

use Illuminate\Mail\Mailables\Address;

public function envelope(): Envelope
{
    return new Envelope(
        from: new Address('tanaka@test.com','田中テスト'),
        subject: 'Contact Admin Mail',
    );
}

②メールの本文の設定

メールにはHTMLメールとテキストメールの2種類が存在する。
laravelでは、マルチパート配信という受信側の環境に合わせて自動的にHTMLメールとテキストメールを振り分ける機能も存在する。

メールの本文もbladeファイルで作成する。
厳密なルールは存在しないが、慣例的に下記のディレクトリを作成して、
その中にbladeファイルを作成する。

/resources/views/emails

③送信先を設定して送信

最後に、Mailクラスを使用してこれまでの設定をもとに送信する。
toメソッドで送信先を指定し、メソッドチェーンでsendメソッドで作成したMailableインスタンスを指定。
※Mailクラスを使用するには、下記のインポートが必要
use Illuminate\Support\Facades\Mail;

Mail::to(‘送信先’)->send(new Mailableインスタンス);

use Illuminate\Support\Facades\Mail;

Mail::to('user@example.com')->send(new ContactAdminMail());

※ContactAdminMail()は①で作成したMailableインスタンス

メール内容の動的化

Mailableクラス内で定義したパブリックプロパティ(public 変数名)は、自動的にビュー内で使用が可能

Database

マイグレーションとは

データベースのテーブル定義をPHPコードで管理するもの。
phpMyAdminから手動はなく、マイグレーションファイルという専用のファイルでテーブル定義を管理しておくと
別のPCや複数人での開発時に、全てのPCで手動でテーブル定義を行わなくて済み、 設定ミスを防いだり時短になる。

マイグレーションファイルの作成コマンド
php artisan make:migration マイグレーションファイル名

※マイグレーション名はスネークケースで指定します(単語ごとにアンダースコアでつなげる。 全て小文字)
※マイグレーションファイルを、「create_○○」で始めるとlaravelがtable作成用のマイグレーションファイルだと認識して、自動でひな形のファイルを作成してくれる。

php artisan make:migration create_test_table

マイグレーションの実行

マイグレーションファイルを作成して、table内容を定義しただけでは、データベースには反映されない。
データベースに反映させるには、下記のコードでマイグレーションを実行する必要がある。

php artisan migrate

※上記のコマンドを実行した際、すでに実行炭のものはスキッブされ、未実行のものだけが実行される。

テーブルの新規作成

Schemaクラスcreateメソッドを使用する。
※マイグレーションファイル内のupメソッド内に記載

Schema::create(‘作成するテーブル名’, function (Blueprint $table) {
~実行文~
});

Schema::create('blogs', function (Blueprint $table) {
    $table->id();
    $table->string('titile',200); //第2引数を指定すると文字数制限
    $table->string('images');
    $table->text('body'); //string型だと16000文字くらいしか扱えない。htmlタグとかを使うコンテンツの場合、より多くの文字を扱えるtext型が良い。
    $table->timestamps();
});

マイグレーション時によく使うカラム設定用のメソッド

カラム指定

メソッド用途
->boolean()論理型
->date()年-月-日
->dateTime()年-月-日 時:分秒
->float()小数
->integer()整数
->string()文字列(最大16,383文字)
->text()文章(HTMLタグなど含め)
->id()主キー用
->foreignid()外部キー用
->timestamps()作成日、更新日用
->softDeletes()論理削除用

カラム修飾子

メソッド用途
->nullable()NULL許可 (デフォルトは拒否)
引数にfalseでNULL拒否
->unsigned()整数値が非負の値(0以上)であることを示す。
(デフォルトは負の値と正の値を受け入れる)
->autoIncrement()整数型のカラムに自動増分(オートインクリメント)属性を追加
(つまりカウントアップ)
->comment(“コメント”)コメント (カラムの説明など)
->after(‘title’)カラムを指定したカラムの「後に」配置
->first()テーブルの「最初に」 カラムを配置

テーブル内容の更新

カラムのリネームと削除には、 doctrine/dbalパッケージが必要なため
下記コマンドにて事前にインストールが必要です。

php composer require doctrine/dbal

ただし、カラム名の変更とカラムの削除はシステム改修やデータの損失を伴う事が多いため、あまりおすすめしません

Schema::table (‘contacts’, function (Blueprint $table) {
~実行文~
});

Schema::table ('contacts', function (Blueprint $table) {
    $table->string('phone',20)->nullable()->change(); // カラム属性更新 (NULL許可)
    $table->text('body'); //追加
    $table->renameColumn('nail_address', 'email'); // カラム名の変更
    $table->dropColumn('gender'); // カラム削除
});

テーブルの削除

Schema::drop(‘contacts’)

おまけ

電話番号の正規化

日本の電話番号のフォーマットを確認し、正規表現を行う。

日本の電話番号のルール
//上記を考慮した正規表現

/^0(\d-?\d{4}|\d{2}-?\d{3}|\d{3}-?\d{2}|\d{4}-?\d|\d0-?\d{4})-?\d{4}$/
上記正規表現の解説

名前付き引数

PHP8.0から追加された引数を柔軟に指定できる機能。
関数の引数は通常、指定順にセットされるが、引数名を指定すると指定順に関係なくセットする事ができる
そのため、引数を渡す順番を柔軟に設定できたり、
引数が多い関数を利用する際、全ての引数を指定することなくピンポイントで引数を指定する事が可能になる。

ただし、バージョンの変更等で関数の引数名が変わる可能性もあるため、
「普遍的な引数名」もしくは「自作関数」以外での利用は避けた方が良い。

引数の順番を変えた場合

arry_fill関数で名前付き引数を利用した場合の挙動。名前付き引数を利用すれば④のように引数の順番を変えても、意図した動作になる。

指定する引数を省略した場合

number_format関数で名前付き引数を利用した場合の挙動。2番目と3番目の値はデフォルト値で良いのでわざわざ指定する必要が無い時、名前付き引きする

コンストラクタのプロモーション

PHP8.0から追加された機能で、コンストラクタの引数をプロパティに昇格する短縮記法。
コンストラクタの引数にアクセス修飾子(public, protected ,private)を指定すると、
自動的にその引数名のプロパティ定義と代入が行われる。
※下記の①②は同じ

①従来の記述方法

public string $str
public function __construct(string $str) {
    $this->str = $str;
}

②コンストラクタのプロモーション

public function __construct(public string $str) {

}

※タイプヒンティングとは:
アクセス修飾子(public, protected ,private)の後にデータ型を指定しておくことで、指定したデータ型のみの引数を許可し、データ型が異なった際にエラーにできる。この振る舞いにより、意図しないデータ型の受け取りを拒否する事ができるため、バグが起きにくくなる。

この記事を書いた人

目次