こんにちは、かつコーチです。
前回はMiddlewareで共通処理を挟む仕組みを解説しました。
Route → Controller → Middlewareと進み、ようやくアプリの「表側」、つまり画面の見た目を作る部分にたどり着きました。
Laravelでは、画面を作るためにBladeというテンプレートエンジンを使います。
今回は、Bladeの基本文法をひと通り押さえていきましょう。
Bladeとは?
テンプレートエンジンの役割
Bladeとは、Laravelに標準で組み込まれているテンプレートエンジンです。
テンプレートエンジンとは、HTMLの中にプログラムの処理(変数の表示や条件分岐、繰り返しなど)を埋め込めるようにする仕組みのことです。
PHP編で、PHPのコードとHTMLを混在させて動的なページを作る方法を扱いましたが、そのまま素のPHPでHTMLに変数を埋め込んでいくと、<?php echo と ?> だらけになって読みにくくなりがちです。
Bladeを使うと、こうした記述をよりシンプルな見た目で書けます。
ファイルの場所と拡張子
Bladeのテンプレートファイルは resources/views/ フォルダに置き、拡張子は .blade.php です。
たとえば resources/views/articles/index.blade.php を作ると、Controllerから次のように呼び出せます。
<?php
namespace App\Http\Controllers;
class ArticleController extends Controller
{
public function index()
{
return view('articles.index');
}
}
view('articles.index') は、resources/views/articles/index.blade.php を指しています。
フォルダの区切り(/)がドット(.)に変わる点に注意してください。
変数を表示する:{{ }}
基本の書き方
Controllerから渡した変数をBlade側で表示するには、二重の波括弧 {{ }} を使います。
<?php
namespace App\Http\Controllers;
class ArticleController extends Controller
{
public function show($id)
{
return view('articles.show', [
'title' => '初めてのLaravel',
'id' => $id,
]);
}
}
{{-- resources/views/articles/show.blade.php --}}
<h1>{{ $title }}</h1>
<p>記事ID:{{ $id }}</p>
view() の第2引数に連想配列で渡した title と id が、Blade側では $title、$id という変数としてそのまま使えます。
素のPHPだと <?php echo $title; ?> のように書く必要がありましたが、Bladeでは {{ $title }} と書くだけで済みます。
自動でエスケープされる
{{ }} のもう一つの重要な役割が、自動エスケープです。
エスケープとは、HTMLタグとして解釈されると困る文字列(<script> タグなど)を、そのまま無害な文字として表示する処理のことです。
{{ $comment }}
たとえ $comment の中に <script>alert('危険')</script> のような文字列が入っていても、Bladeの {{ }} は自動的にエスケープしてから表示するので、悪意のあるスクリプトがそのまま実行されることはありません。
これはXSS(クロスサイトスクリプティング)という攻撃を防ぐ、重要なセキュリティ機能です。
エスケープをしたくない特別な理由がない限り、変数の表示には必ず {{ }} を使うようにしましょう。
条件分岐:@if
基本の書き方
PHPの if 文に相当する処理は、@if ディレクティブ(Bladeの特殊な命令)で書きます。
@if ($articles->count() > 0)
<p>記事が {{ $articles->count() }} 件あります。</p>
@else
<p>まだ記事がありません。</p>
@endif
@if と @endif の間が条件分岐の範囲になり、@else で「それ以外の場合」を表現できます。
PHP編で学んだ elseif に相当するものは @elseif です。
@if ($score >= 90)
<p>評価:A</p>
@elseif ($score >= 70)
<p>評価:B</p>
@else
<p>評価:C以下</p>
@endif
条件分岐で使う >= や && などの演算子は、PHPの記事で解説したものとまったく同じです。
繰り返し処理:@foreach
一覧表示の基本形
記事一覧やユーザー一覧など、配列やコレクション(Laravelがデータベースの結果などを扱うための特別な配列のようなもの)をループで表示するには @foreach を使います。
<ul>
@foreach ($articles as $article)
<li>{{ $article->title }}</li>
@endforeach
</ul>
PHPの foreach とほぼ同じ書き方で、@foreach と @endforeach で囲んだ範囲が、配列の要素の数だけ繰り返し表示されます。
$loop変数で繰り返しの情報を使う
Bladeの @foreach の中では、$loop という特別な変数が自動的に使えるようになっています。
<ul>
@foreach ($articles as $article)
<li>
{{ $loop->iteration }}件目:{{ $article->title }}
@if ($loop->first)
(最初の記事です)
@endif
@if ($loop->last)
(最後の記事です)
@endif
</li>
@endforeach
</ul>
$loop->iteration は今何周目かを表す番号、$loop->first と $loop->last はそれぞれ最初の要素・最後の要素かどうかを表す真偽値です。
素のPHPで同じことをやろうとすると、自分でカウンター用の変数を用意する必要がありますが、Bladeなら最初から用意されているので手間がかかりません。
レイアウトの継承:@extends と @section
共通レイアウトを使い回す
複数のページで共通のヘッダー・フッターを使い回したいとき、ページごとに同じHTMLをコピーするのは非効率です。
Bladeには、レイアウトの継承という仕組みがあり、共通部分を1つのファイルにまとめられます。
まず、共通レイアウトを定義します。
{{-- resources/views/layouts/app.blade.php --}}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>@yield('title', 'かつコーチのLaravel入門')</title>
</head>
<body>
<header>
<h1>かつコーチのLaravelブログ</h1>
</header>
<main>
@yield('content')
</main>
<footer>
<p>© 2026 かつコーチ</p>
</footer>
</body>
</html>
@yield('content') は、「ここに各ページ固有の内容が差し込まれますよ」という目印です。
続いて、この共通レイアウトを使う個別ページを作ります。
{{-- resources/views/articles/index.blade.php --}}
@extends('layouts.app')
@section('title', '記事一覧')
@section('content')
<h2>記事一覧</h2>
<ul>
@foreach ($articles as $article)
<li>{{ $article->title }}</li>
@endforeach
</ul>
@endsection
@extends('layouts.app'):layouts/app.blade.phpを土台として使う宣言@section('content') 〜 @endsection:土台側の@yield('content')の位置に差し込む内容
この仕組みによって、ヘッダー・フッターのHTMLを何十ページ分もコピーする必要がなくなります。
つまずきやすいポイント:{{ }}と{!! !!}の使い分け
エスケープしないための構文
Bladeには {{ }} の他に {!! !!} という書き方もあり、私はこの違いを理解しないまま使ってしまい、意図せずセキュリティ上のリスクを招きかけたことがあります。
❌ Before:ユーザー入力をそのまま{!! !!}で表示する
{{-- お問い合わせフォームのコメント欄をそのまま表示 --}}
<div class="comment">
{!! $comment !!}
</div>
{!! !!} はエスケープを行わずに、変数の中身をそのままHTMLとして出力する構文です。
もし $comment にユーザーが入力した <script> タグが含まれていた場合、それがそのままブラウザで実行されてしまい、XSS攻撃を許してしまう可能性があります。
✅ After:ユーザー入力は{{ }}でエスケープして表示する
<div class="comment">
{{ $comment }}
</div>
ユーザーが入力した内容を表示する場合は、必ず {{ }} を使ってエスケープするのが基本です。
{!! !!} を使ってよいのは、管理者だけが編集できるお知らせ文など、信頼できる側だけがHTMLを入力する場面に限られます。
「ユーザーからの入力を表示するときは {{ }}、それ以外に理由があって生のHTMLを表示したいときだけ {!! !!}」というルールを徹底しておくと、事故を防げます。
私はこの区別を知らずに、管理画面用に書いたコードをそのままコピーしてユーザー入力の表示に流用してしまい、後から指摘を受けて青ざめた経験があります。
セキュリティに関わる部分なので、迷ったときは必ず {{ }} を選ぶようにしましょう。
まとめ
この記事のポイント
- Bladeは
resources/views/に.blade.phpの拡張子で置くLaravel標準のテンプレートエンジン - 変数の表示は
{{ $変数名 }}。自動でエスケープされ、XSS対策になる @if・@foreachで条件分岐や繰り返しを、素のPHPよりシンプルに書ける@extends・@yield・@sectionでレイアウトを継承し、共通部分を使い回せる{!! !!}はエスケープされないため、ユーザー入力の表示には基本的に使わない
次に読むべき記事
Bladeの基本文法が身についたら、次はヘッダーやボタンなどのパーツを部品化して再利用する、Bladeコンポーネントを学んでいきましょう。
→ 次の記事:Bladeコンポーネントで再利用可能なパーツを作る