Skip to content

Instantly share code, notes, and snippets.

@kita127
Last active August 27, 2022 06:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kita127/57576ea8082fa6efeceb816c754e96ed to your computer and use it in GitHub Desktop.
Save kita127/57576ea8082fa6efeceb816c754e96ed to your computer and use it in GitHub Desktop.

Laravel ノウハウメモ

Laravel についての個人的なメモ書き.
Sail を使用している前提で記載.

無分類

フラッシュセッションデータの利用

一度きりしか表示されないデータ.

コントローラ

    public function __invoke(Request $request)
    {
        return redirect()
            ->route('hoge.update.index', ['hogeId' => $hoge->id])
            ->with('feedback.hoge', "ほげ");
    }

ビュー

    @if (session('feedback.hoge'))
        フラッシュデータが定義されている場合表示される
    @endif

パスパラメータを取得する

ルーター

Route::get('/hoge/update/{hogeId}', \App\Http\Controllers\Hoge\Update\IndexController::class)->name('hoge.update.index')
    ->where('hogeId', '[0-9]+');

where メソッドでパラメータの入力制限も可能. 上記は0から9の文字列だけを制限している.

コントローラ

    public function __invoke(Request $request)
    {
        $hogeId = (int) $request->route('hogeId');
    }

いちいちパスパラメータの指定が面倒な場合はグローバルに設定も可能. app/Providers/RouteServiceProvider.php に以下を追記する.

public function boot()
{
    Route::pattern('hogeId', '[0-9]+');
}

コントローラでリダイレクト

    public function __invoke(Request $request)
    {
        return redirect()->route('hoge.index');
    }

PUT リクエスト

HTML には GET と POST しかないため, @method ディレクティブで PUT を指定する.

ビュー

    <form action="{{ route('hoge.update.put') }}" method="post">
        @method('PUT')
        @csrf

ルーター

Route::put('/hoge/update', \App\Http\Controllers\Hoge\Update\PutController::class)->name('hoge.update.put');

ミドルウェアの作成

以下のコマンドで Middleware を作成する.

$ sail artisan make:middleware HogeMiddleware

ミドルウェアを登録する.
アプリケーション全体に効かせる場合は以下に追加.

app/Http/Kernel.php

    protected $middleware = [
        // \App\Http\Middleware\TrustHosts::class,
        \App\Http\Middleware\TrustProxies::class,
        \Illuminate\Http\Middleware\HandleCors::class,
        \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    ];

個別に設定する場合は以下にエイリアスと共に追加.

app/Http/Kernel.php

    protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
        'hoge' => \App\Http\Middleware\HogeMiddleware::class,
    ];

以下にミドルウェアの実装を施す.

app/Http/Middleware/HogeMiddleware

    public function handle(Request $request, Closure $next)
    {
        /* 前に処理を実行したい場合はここに実装する */
        return $next($request);
        /* 後に処理を実行したい場合はここに実装する */
    }

Artisan

Eloquentモデルの生成 Factory の生成

$ sail artisan make:model Hoge -f 

交差テーブルの Eloquentモデル生成

$ sail artisan make:model HogeFuga --pivot

マイグレーション

マイグレーションとシーディングのやり直し

$ sail artisan migrate:fresh --seed

特定のカラムの後にカラムを追加

id の後に user_id を追加.
down にはマイグレーションを取り消す際のコマンドを記載.

対象のマイグレーションファイル

    public function up()
    {
        Schema::table('hoges', function (Blueprint $table) {
            $table->unsignedBigInteger('user_id')->after('id');
        });
    }

    public function down()
    {
        Schema::table('hoges', function (Blueprint $table) {
            //
            $table->dropColumn('user_id');
        });
    }

外部キー制約を設定する

users テーブルの id に user_id を関連づける.
users テーブルに存在する id だけが user_id に登録できるようになる.

down する際の引数の命名ルールは「テーブル名+カラム名+foreign」をスネークケースで表現する.

    public function up()
    {
        Schema::table('hoges', function (Blueprint $table) {

            // usersテーブルのidカラムにuser_idカラムを関連付ける
            $table->foreign('user_id')->references('id')->on('users');
        });
    }

    public function down()
    {
        Schema::table('hoges', function (Blueprint $table) {
            //
            $table->dropForeign('hoges_user_id_foreign');
        });
    }

モデル(Eloquent)

モデルを取得する

firstOrFail は最初の結果を取得する. 見つからなかった場合は Illuminate\Datebase\Eloquent\ModelNotFoundException を投げる.

$hogeId = (int) $request->route('hogeId');
$hoge = Hoge::where('id', $hogeId)->firstOrFail();

モデル同士の関連付け

モデル同士を関連付け情報を取得することが可能.

部署モデル(department)と従業員モデル(employe)があった場合, 部署は複数の従業員を持ち, 従業員はひとつの部署にのみ所属するという関係性になる.
その関係性をコードで表現すると以下.

app/Model/Department.php

class Department extends Model
{
    public function employes()
    {
        return $this->hasMany(Employe::class);
    }
}

app/Model/Employe.php

class Employe extends Model
{
    public function department()
    {
        return $this->belongsTo(Department::class);
    }
}

以上を実装することで例えば従業員が所属する部署名を取得したりなど可能となる.

{{ $employe->department->name }}

Breeze(ログイン機能)

登録・ログイン後に遷移するページの指定

app/Providers/RouteServiceProvider.php

public const HOME = '/hoge';

ログアウト後に遷移するページの指定

ログアウト時は Breeze で作成された AuthenticatedSessionControllerdestroy メソッドが実行されるためそこを修正する.

public function destroy(Request $request)
{
    ... 省略 ...

    return redirect('/hoge');
}

ログインユーザーのみ処理可能にする

route/web.php

Route::get('/hoge', \App\Http\Controllers\HogeController::class)->middleware('auth')->name('hoge');

複数まとめたい場合は以下.

route/web.php

Route::middleware('auth')->group(function () {
    Route::post('/hoge/create', \App\Http\Controllers\Hoge\CreateController::class)->name('hoge.create');
    Route::get('/hoge/update/{hogeId}', \App\Http\Controllers\Hoge\Update\IndexController::class)->name('hoge.update.index')->where('hogeId', '[0-9]+');
    Route::put('/hoge/update/{hogeId}', \App\Http\Controllers\Hoge\Update\PutController::class)->name('hoge.update.put')->where('hogeId', '[0-9]+');
    Route::delete('/hoge/delete/{hogeId}', \App\Http\Controllers\Hoge\DeleteController::class)->name('hoge.delete');
});

ログインしている人にだけ表示する

@auth ディレクティブを使う.

@auth
    <div class="p-4">
        <form action="{{ route('hoge.create') }}" method="post">
            @csrf
            ...
@endauth

ゲスト(ログインしていない)にだけ表示する

@guest
    <div class="flex flex-wrap justify-center">
    ...
@endguest

ログインしているユーザーを取得

Request クラスから取得可能.

app/Http/Requests/HogeRequest.php

class HogeRequest extends FormRequest
{
    ...
    public funtion userId() :: int
    {
        return $this->user()->id;
    }
}

Blade から取得する場合は以下.

\Illuminate\Support\Facades\Auth::id()

例外処理

403 FORBIDDEN

以下の例外を投げる.

throw new AccessDeniedHttpException();

Blade(テンプレート)

ループの最後の要素を判定

@if ($loop->last)

1度だけ読み込みたい

@once ディレクティブを使用する.
リストなどの繰り返しで複数回読み込まれても @once ディレクティブを使用すれば1度の読み込みだけとなる.

@once
    ... 省略 ...
@endonce

特定のページのみに追加したい

@push@stack ディレクティブを使用する.

コンポーネント側で @push ディレクティブを書く.

@push('css')
    // CSS や JavaScript などを書く
@endpush

利用側で @stack ディレクティブを書く. @push した CSS や JavaScript が展開される.

<div>
    @stack('css')
</div>

変数の内容を HTML として表示する

<p>{!! nl2br(e($content)) !!}</p>
  • {!! !!} を使用し, HTML タグをエスケープしないで主力
    • {{ }} の場合はエスケープされ以下のような表示になる
    • <h1>hello</h1> -> &lt;h1&gt;hello&lt;/h1&gt;
  • Laravel 提供の関数 e で特殊文字をエスケープ
  • PHP 組み込み関数 nl2br で改行コードを HTML の <br> タグに変換

php プログラムを書く

@php ディレクティブを使用する.

@php
    ... PHP での処理 ...

@endphp

匿名コンポーネント

Laravelバージョン7以降のコンポーネント機能について.

resources/views/components/以下にテンプレートを作成する.

resources/views/components/layout.blade.pnp

<!doctype html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0,
          maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link href="{{ mix('/css/app.css') }}" rel="stylesheet">
    <script src="{{ mix('/js/app.js') }}"></script>
    <title>{{ $title ?? 'ほげほげアプリ' }}</title>
    @stack('css')
</head>

<body class="bg-gray-50">
    {{ $slot }}
</body>

</html>

以下の通り <x-テンプレート名> のタグで埋め込む.

resources/views/hoge/index.blade.php

<x-layout title="TOP | ほげほげアプリ">
    <h1>ここに内容が入ります</h1>
<x-layout>

以下の様な HTML に展開される.

<!doctype html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0,
          maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link href="/css/app.css?id=xxxxxxxxxxxxxxxxx" rel="stylesheet">
    <script src="/js/app.js?id=yyyyyyyyyyyyyyyyyyy"></script>
    <title>TOP | ほげほげアプリ</title>
</head>

<body class="bg-gray-50">
    <h1>ここに内容が入ります</h1>
</body>

</html>

上記の $title は外部から渡せる変数で props という. $slot に利用する側のタグを埋め込める.

props に変数を使用する

props に変数を設定する場合は :title="$title" のように属性の前にコロンをつける.

複数の slot を使用する

複数 slot が必要な場合は名前付き slot を使用する.

resources/views/components/layout.blade.pnp

<!doctype html>
<html lang="ja">

<head>
    ...
    <title>{{ $title ?? 'つぶやきアプリ' }}</title>
</head>

<body class="bg-gray-50">
    {{ $slot }}
    <aside>{{ $aside }}</aside>
</body>

</html>

aside という名までで slot を作った場合, 以下の様に利用する.

resources/views/hoge/index.blade.php

<x-layout title="TOP | ほげほげアプリ">
    <h1>ここに内容が入ります</h1>
    <x-slot name="aside">追加したslot</x-slot>
<x-layout>

props にデフォルト値を与える

@props ディレクティブを使用しデフォルト値を設定したい props と値の連想配列を設定する.

@props([
    'title' => 'タイトル',
])

クラスベースコンポーネント

Artisan コマンドを実行する.

$ sail artisan make:component Hoge/Options

resources/views/components/hoge/options.blade.phpapp/View/Components/Hoge/Options.php が生成される.

作成された Options.php からクラスベースコンポーネントが呼び出される.
コンストラクタの引数は props で渡される値. コンポーネント自体で処理をしたい場合はクラスベースコンポーネントを使用するとよい.

app/View/Components/Hoge/Options.php

class Options extends Component
{
    private int $hogeId;
    private int $userId;
    /**
     * Create a new component instance.
     *
     * @return void
     */
    public function __construct(int $hogeId, int $userId)
    {
        //
        $this->hogeId = $hogeId;
        $this->userId = $userId;
    }

    /**
     * Get the view / contents that represent the component.
     *
     * @return \Illuminate\Contracts\View\View|\Closure|string
     */
    public function render()
    {
        return view('components.hoge.options')
            ->with('hogeId', $this->hogeId)
            ->with('myHoge', \Illuminate\Support\Facades\Auth::id() ===
                $this->userId);
    }
}

コンポーネント利用側は以下の感じ

<div>
    <x-hoge.options :hogeId="$hoge->id" :userId="$hoge->user_id">
    </x-hoge.options>
</div>

Vue の導入

環境

  • Laravel Framework 9.21.5
  • Vue 3.2.37
  • laravel-mix 6.0.49"

参考

以下の記事を参考に設定.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment