LLaravel Bootcamp

Day 5入力の検証と横断的関心事 — バリデーション・ミドルウェア・Blade

Blade — 表示に専念するテンプレート

継承とコンポーネントで再利用し、XSSを自動エスケープ。ロジックをビューに書かない理由。

Bladeとは

はLaravel標準のテンプレートエンジンです。HTMLの中に「{{ }}」で変数を埋め込んだり、「@if」「@foreach」で簡単な制御を書いたりできます。最終的に素のPHP+HTMLにコンパイルされるため高速です。

XSSの自動エスケープ

Bladeの「{{ $value }}」は、値を自動的にHTMLエスケープして出力します。ユーザーが入力した文字列にスクリプトタグが含まれていても、そのまま実行されず文字として表示されます。これがXSS(クロスサイトスクリプティング)対策の基本になります。

エスケープを外して生HTMLを出す(危険)

Blade
{{-- ユーザー入力をそのままHTMLとして出力 --}}
{!! $userComment !!}
{{-- $userComment<script>...</script> が含まれると実行されてしまう --}}

既定の {{ }} で自動エスケープ(安全)

Blade
{{-- 文字として安全に表示される --}}
{{ $userComment }}
{{-- <script>&lt;script&gt; に変換され、実行されない --}}

{!! !!} は原則使わない

「{!! !!}」はエスケープを外して生のHTMLを出力します。信頼できる管理者が用意した定型HTMLなど、限られた用途以外では使うべきではありません。ユーザー入力に対して使うとXSSの穴になります。

レイアウトの継承

Blade
{{-- resources/views/layouts/app.blade.php --}}
<html>
  <body>
    <header>共通ヘッダー</header>
    <main>
      @yield('content')  {{-- 各ページの中身がここに入る --}}
    </main>
  </body>
</html>

{{-- resources/views/posts/index.blade.php --}}
@extends('layouts.app')

@section('content')
  <h1>記事一覧</h1>
  @foreach ($posts as $post)
    <article>{{ $post->title }}</article>
  @endforeach
@endsection
共通レイアウトを1つ作り、各ページはそれを継承する

コンポーネントによる再利用

Blade
{{-- resources/views/components/alert.blade.php --}}
<div class="alert alert-{{ $type }}">
    {{ $slot }}  {{-- タグの中身がここに入る --}}
</div>

{{-- 使う側 --}}
<x-alert type="danger">
    保存に失敗しました。
</x-alert>
繰り返し使うUIを部品化する

なぜビューにロジックを書かないのか

ビューの責務は『渡されたデータをどう見せるか』だけです。集計や条件分岐の判断、DBアクセスをビューに書くと、同じ計算が複数のビューに散らばり、テストもできず、デザイナーとの分業も崩れます。判断はコントローラやサービス層で終わらせ、ビューには結果だけを渡す——これが表示と処理を分ける(MVCの)基本です。

ビューで集計・判断してしまう

Blade
{{-- ビュー内でDBアクセスや集計をしている --}}
@php
    $total = \App\Models\Order::where('user_id', $userId)->sum('amount');
    $rank  = $total > 100000 ? 'ゴールド' : '一般';
@endphp
<p>あなたのランク: {{ $rank }}</p>

計算は事前に済ませ、ビューは表示だけ

Blade
{{-- コントローラ/サービスで $rank を算出済みにして渡す --}}
<p>あなたのランク: {{ $rank }}</p>

面接ではこう言う

「Bladeでは {{ }} が自動でエスケープするので、XSS対策の基本がテンプレート側で効いています。ビューの責務は表示だけと考えているので、集計や判断はコントローラやサービス層で終わらせて、ビューには結果だけを渡します。共通部分はレイアウト継承やコンポーネントで再利用します」

読んでも腑に落ちない所は、AIに噛み砕いてもらいましょう。

理解度チェック

答えられれば、面接で説明できる状態に一歩近づきます。

Q1

Bladeの「{{ $value }}」が既定で行うことは?

Q2

ビューにロジックを書くべきでない理由として、最も適切なものは?

Q3

「ロジックをビューに書かない」とはどういう方針か、理由とともに説明してください。

記述式です。まず自分の言葉で答えを考えてから、模範解答を開いて自己採点してください。