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');
}
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);
/* 後に処理を実行したい場合はここに実装する */
}
$ sail artisan make:model Hoge -f
$ 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');
});
}
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 }}
app/Providers/RouteServiceProvider.php
public const HOME = '/hoge';
ログアウト時は Breeze で作成された AuthenticatedSessionController
の destroy
メソッドが実行されるためそこを修正する.
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()
以下の例外を投げる.
throw new AccessDeniedHttpException();
@if ($loop->last)
@once
ディレクティブを使用する.
リストなどの繰り返しで複数回読み込まれても @once
ディレクティブを使用すれば1度の読み込みだけとなる.
@once
... 省略 ...
@endonce
@push
と @stack
ディレクティブを使用する.
コンポーネント側で @push
ディレクティブを書く.
@push('css')
// CSS や JavaScript などを書く
@endpush
利用側で @stack
ディレクティブを書く. @push
した CSS や JavaScript が展開される.
<div>
@stack('css')
</div>
<p>{!! nl2br(e($content)) !!}</p>
{!! !!}
を使用し, HTML タグをエスケープしないで主力{{ }}
の場合はエスケープされ以下のような表示になる<h1>hello</h1>
-><h1>hello</h1>
- Laravel 提供の関数
e
で特殊文字をエスケープ - PHP 組み込み関数
nl2br
で改行コードを HTML の<br>
タグに変換
@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 に変数を設定する場合は :title="$title"
のように属性の前にコロンをつける.
複数 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([
'title' => 'タイトル',
])
Artisan コマンドを実行する.
$ sail artisan make:component Hoge/Options
resources/views/components/hoge/options.blade.php
と app/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>
- Laravel Framework 9.21.5
- Vue 3.2.37
- laravel-mix 6.0.49"
以下の記事を参考に設定.