ブログ名

PHP LaravelでWEBアプリ開発 【ビュー②】

前回の記事(https://www.itd-blog.jp/entry/laravel-5)ではPHPテンプレートを紹介しました。 今回はもう一つのテンプレートであるBladeテンプレートについて解説していきます。

Bladeテンプレートとは

「Blade」とは、Laravelに用意されている独自のテンプレートエンジンです。 前回紹介したPHPテンプレートはわかりやすいのが長所ですが、単に値を表示するだけでも、 <?php echo 〇〇; ?>と記述する必要があるため、煩雑になってしまう欠点があります。 また、PHPタグはHTMLタグと同じ形式のため、HTML作成ツールなどを使用するとタグの構成が崩れたりすることもあり、ページをいくつかに分割してまとめてレイアウトする機能などもありません。 Laravel独自に用意されている「Blade」テンプレートエンジンは、非常に効率的にレイアウトを作成していくための機能をもっています。 テンプレートを継承して新たなテンプレートを定義したり、レイアウトの一部をセクションとしてはめ込むなどしてレイアウトを作成していくことが可能です。

テンプレート作成

では実際にBladeテンプレートを利用してみましょう。

Bladeテンプレートも、PHPテンプレート度同様に「resources」フォルダ内の「view」フォルダ内に作成します。 「view」フォルダ内に作成した「hello」フォルダの中に、「index.blade.php」という名前でファイルを作成しましょう。これがBladeのテンプレートファイルとなります。 Bladeはこのように「○○.blade.php」という名前でファイルを作成します。 「index.blade.php」には以下のように記述しておきます。

[index.blade.php]

<html>
<head>
    <title>Hello/Index</title>
    <style>
    p {font-size:24pt; text-align:center;}
    </style>
</head>
<body>
    <p>{{ $msg }}</p>
</body>
</html>

基本的な部分は普通のHTMLそのままとなっています。 \

タグの部分に、{{ $msg }}という記述がありますが、これは変数$msgを埋め込んだものです。 Bladeでは{{ $変数 }}というようにして、変数をテンプレートに埋め込むことができます。

アクションメソッドの修正

では続いてコントローラのアクションメソッドを修正しましょう。 indexアクションメソッドを、以下のように書き換えます。

[HelloController.php]

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class HelloController extends Controller
{
    public function index() {
        $data = [
            'msg' => 'Bladeテンプレートのサンプル',
        ];
        return view('hello.index', $data);
    }
}

これで完成です。 /helloにアクセスすると、index.blade.phpテンプレートを使用して画面が表示されます。

f:id:iTD_GRP:20190829104609p:plain

ところで、/helloにアクセスしたときにindex.blade.phpを使用して画面が表示されましたが、これはなぜでしょうか?Bladeテンプレートを読み込むといったような設定の変更などは行っていませんし、前回の記事で作成したindex.phpもそのままです。にも関わらず、view('hello.index'~)を実行すると、index.blade.phpを使用して画面が表示されました。 Laravelでは、Bladeテンプレートが存在する場合は優先的に読み込まれるようになっています。 index.phpとindex.blade.phpが存在する状況でテンプレート名を'index'と指定した場合、index.blade.phpが使用されます。index.blade.phpがない場合は、index.phpが使用されます。

フォームを利用する

基本的なWebページの表示ができるようになったので、次は「フォーム送信」を行ってみましょう。 フォームとは、ユーザからの入力を受けて処理をする際の基本となるものです。 まずはテンプレートの修正をします。 index.blade.phpの\タグ部分を以下のように修正してください。

[index.blade.php]

<html>
<head>
    <title>Hello/Index</title>
    <style>
    p {font-size:24pt;}
    </style>
</head>
<body>
    <p>{{ $msg }}</p>
    <form method="POST" action="/hello">
        @csrf
        <input type="text" name="msg">
        <input type="submit">
    </form>
</body>
</html>

ここでは、<form method="POST" action="/hello">という形でフォームを用意してあります。 /helloにPOST送信された時の処理を用意すれば、そこで送信されたフォームを処理できるようになります。

CSRF対策について

ところで\

タグの次にある@csrfという記述がありますが、これは何でしょうか? Laravelの@csrfは、クロス・サイト・リクエスト・フォージェリ(CSRF)からアプリケーションを簡単に守るためのものとなります。 CSRF攻撃の詳細な説明は省きますが、POST送信時にこの対策を行っていない場合はエラーとなりますので、忘れずに記述しておきましょう。

アクションの用意

では、コントローラにアクションを用意します。 今回は/helloにアクセスしたときの処理と、フォームを送信したときの処理の二つのアクションが必要となります。 HelloController.phpを以下のように修正してください。

[HelloController.php]

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class HelloController extends Controller
{
    public function index() {
        $data = [
            'msg' => '名前を入力してください。',
        ];
        return view('hello.index', $data);
    }

    public function post(Request $request) {
        $msg = $request->msg;
        $data = [
            'msg' => 'こんにちは' . $msg . 'さん。',
        ];
        return view('hello.index', $data);
    }
}

indexメソッドは、/helloにアクセスした際の処理となります。 postメソッドが、/helloにPOST送信された時の処理です。ここでは引数にRequestインスタンスを用意しています。そして、$msg = $request->msg;のようにフォームの内容を取り出しています。 inputタグでname="msg"と指定してあったフィールドの値を、このように$request->msgで取り出すことができます。フォームで送信された値は、すべてnameのプロパティとして取り出せるようになっています。

POSTのルート設定

最後にルート情報を追加します。 web.phpに以下の分を追加しましょう。なお既にあるRoute::get文は/helloにアクセスする際に使用するので、そのままにしておいてください。

[HelloController.php]

Route::post('hello', 'HelloController@post');

POST送信は、Route::postメソッドで設定します。 メソッド名が異なるだけで、Route::getメソッドと使用方法は同じとなります。 割り当てるアドレスと、呼び出すアクションをそれぞれ引数に指定します。 ここでは/helloにHelloControllerクラスのpostメソッドを割り当てています。 アドレスが同じでも、GETとPOSTのようにアクセスするメソッドの種類が異なれば、両方同時に使用することができます。

Bladeの構文

Bladeでは、レイアウト内で表示の制御をおこなったり、レイアウトを継承して複数を組み合わせたりするための構文が用意されています。 この構文の書き方がわからないと、Bladeの機能を引き出すことはできません。 順に解説しますので、使いこなせるように覚えていきましょう。

値の表示

{{ 値・変数・式・関数など }}

このように、{{ と }} の間に文を記述することで、その文が返す値をその場に書き出します。 値として使用できるものであれば、関数でもメソッドでも指定することが可能です。 この{{}}の出力は、基本的にHTMLエスケープ処理が行われます。そのためHTMLタグを記述してもテキストとして表示されるため、HTMLタグとしては機能しません。 エスケープ処理してほしくない場合は、以下のように記述してください。

{!! 値・変数・式・関数など !!}

{!! と !!} の間に値を設定します。 これで値はエスケープ処理されなくなり、HTMLタグはそのままタグとして機能するようになります。

条件分岐

Bladeには「ディレクティブ」と呼ばれる機能があります。 これは言語における構文のような役割を果たします。 まずは条件分岐(if文)に相当するディレクティブから解説します。

  • 条件がtrueの場合
@if (条件)
……出力内容……
@endif
  • 条件によって出力内容を変える場合
@if (条件)
……出力内容……
@else
……出力内容……
@endif
  • 複数条件を設定する場合
@if (条件)
……出力内容……
@elseif
……出力内容……
@else
……出力内容……
@endif

ディレクティブは基本的に「@ディレクティブ名」という形で記述します。 @ifはその後に条件を設定します。 この@ifには@elseと@elseifというディレクティブがオプションとして用意されています。 基本的にはPHPのif文と同じ働きをします。違いは、ディレクティブの場合は何かを実行するのではなく「表示する」という点です。条件によって表示する内容を制御するのが@ifディレクトリです。

続いて、@if以外の条件分岐を行うディレクティブを紹介します。 いずれも@ifと同様に、@elseをオプションとして追加することが可能です。

  • 条件がfalseの場合
@unless (条件)
……出力内容……
@endunless

@ifと逆の働きをするものです。 条件がfalseの場合に表示を行い、trueの場合には表示をしません。

  • 変数が空の場合
@empty (変数)
……出力内容……
@endempty

()に指定した変数が空の場合に表示を行います。

  • 変数が定義済みの場合
@isset (変数)
……出力内容……
@endisset

変数そのものが定義されているかどうかを確認するものです。 変数が定義されていて、かつnullでない場合に表示を行います。

繰り返し

繰り返し関係のディレクティブも何種類か用意されています。 これらもまとめて解説します。

  • for構文に相当するもの
@for (初期化; 条件; 後処理)
……出力内容……
@endfor

PHPのfor構文に相当するディレクティブです。 for構文と同様に、()内に初期化処理、繰り返し条件、繰り返しの後処理の3つを用意します。

  • foreach構文に相当するもの
@foreach ($配列 as $変数)
……出力内容……
@endforeach

PHPのforeach構文に相当するディレクティブです。 ()内には、配列と変数を用意します。これにより、配列から値を変数へと取り出す処理を繰り返します。

  • foreach-else構文に相当するもの
@forelse ($配列 as $変数)
……出力内容……
@empty
……出力内容……
@endforelse

これはforeach構文にelseを追加した場合の処理に相当するものです。 ()の配列から順に値を取り出して処理を繰り返していき、値をすべて取り出し終えた後は、@emptyにある処理を実行して繰り返しを終了します。

  • while構文に相当するもの
@while (条件)
……出力内容……
@endwhile

PHPのwhile構文に相当するものです。 引数に条件を設定し、その条件がtrueの場合に表示を行います。

@breakと@continue

PHPの繰り返し構文にはbreakやcontinueといったキーワードが用意されていて、これらを使用して繰り返しの中断や次のステップへの継続処理などが行えるようになっています。 繰り返しディレクティブでも、これに相当するものが用意されています。

@break PHPのbreakに相当するものです。

@continue PHPのcontinueに相当するものです。

@phpディレクティブ

ディレクティブは制御構文のような機能をテンプレートに簡単に組み込むことができますが、PHPスクリプトそのものではありません。 ifやforを利用できても、それだけでは複雑な処理を組み立てられるものではありません。 PHPスクリプトを直接実行することも必要となる場合があると思います。 PHPスクリプトは、@phpディレクティブを使用して記述することが可能です。

@php
……PHPスクリプト……
@endphp

このディレクティブを使用すれば、Bladeテンプレート内で直接スクリプトを実行して、必要な処理を行えるようになります。

次回はセクションを組み合わせたレイアウトの作成について解説します。


前の記事へ 目次へ戻る