SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

軽量PHPフレームワークSlimを習得しよう

エラー処理をSlimに任せるエラーハンドラを使ってみよう

軽量PHPフレームワークSlimを習得しよう 第9回

エラー画面のカスタマイズ

 エラーミドルウェアを登録することで、全てのエラーや例外処理をSlimが担うことになり、その結果Slimオリジナルのエラー画面が表示されるようになりました。ここから、この画面をカスタマイズする方法を紹介します。

エラーレンダラクラスによるエラー画面のカスタマイズ

 Slimで独自のエラー画面を表示させるには、まず、エラー画面を表示させるクラスであるエラーレンダラクラスを作成する必要があります。それは例えば、リスト2のコードです。

[リスト2]firstslim/src/classes/exceptions/CustomErrorRenderer.php
<?php
namespace CodeZineSlim\FirstSlim\exceptions;

use Throwable;
use Psr\Container\ContainerInterface;
use Slim\Interfaces\ErrorRendererInterface;

class CustomErrorRenderer implements ErrorRendererInterface
{
	private $container;  // (1)
	// (2)
	public function __construct(ContainerInterface $container)
	{
		$this->container = $container;
	}
	// (3)
	public function __invoke(Throwable $exception, bool $displayErrorDetails): string
	{
		$twig = $this->container->get("view");  // (4)
		$assign["errorMsg"] = "もう一度初めから操作してください。";  // (5)
		$returnHtml = $twig->fetch("error.html", $assign);  // (6)
		return $returnHtml;  // (7)
	}
}

 アプリケーションの中で、例外処理関係のクラスは1つのフォルダにまとめておいた方が良いでしょう。そこで、ここではclasses/exceptionsフォルダを作成し、その中にリスト2のエラーレンダラクラスを格納することにしています。

 そのエラーレンダラクラスは、\Slim\Interfaces\ErrorRendererInterfaceインターフェースを実装する形で作成します。記述する必要があるメソッドは__invoke()です。メソッドシグネチャはリスト2の(3)にあるように、第1引数はThrowable型の$exceptionで、この第1引数に現在発生した例外インスタンスが渡されます。第2引数はbool型の$displayErrorDetailsで、引数名から分かるように、リスト1の(2)でエラーミドルウェアを登録する際に第1引数として渡した値がそのまま渡ってきます。

 戻り値は、stringと文字列になっています。これは、エラー画面に表示させるHTML文字列を表します。注意しなければならないのは、これまでリクエスト処理の戻り値としてリターンしていたのはレスポンスオブジェクトですが、エラーレンダラクラスでは文字列です。したがって、Twigクラスのrender()メソッドは利用できません。代わりに、テンプレートを元に、HTML文字列を生成してくれるfetch()メソッドを利用します。それがリスト2の(6)です。その際、第1引数としてテンプレートファイルパス、第2引数としてテンプレート変数が格納された連想配列を渡します。

 リスト2では、エラー画面テンプレートとして後で用意するerror.htmlを第1引数として、エラーメッセージのテンプレート変数としてリスト2の(5)で用意した連想配列$assignを、第2引数として渡しています。そのようにして生成されたHTML文字列を(7)のようにリターンすれば、独自のエラー画面として用意されたerror.htmlが表示されるようになります。

 ただし、そのためにはコンテナからTwigインスタンスを取得する必要があります。さらに、コンテナインスタンスをこのエラーレンダラ内で用意しておくことも必要です。そこで、コンストラクタの引数としてコンテナインスタンスを受け取るようにしておき、それをプロパティとして格納しておきます。それが、リスト2の(1)と(2)です。

 こうすることで、Slimはこのエラーレンダラクラスを利用する時に、自動的にコンテナインスタンスを渡してくれます。この仕組みのおかげで、__invoke()メソッド内では、(4)の通りいつでもコンテナ内のインスタンスを取得できるようになります。この考え方は、第6回で紹介した、コントローラクラスでのコンテナの扱いと同じです。

 なお、リスト2の(6)で読み込むerror.htmlとして、例えば、リスト3のようなエラー画面を用意しておくことにします。

[リスト3]firstslim/src/templates/error.html
<!DOCTYPE html>
<html lang="ja">
	<head>
		<meta charset="UTF-8">
		<title>Error</title>
	</head>
	<body>
		<h1>Error</h1>
		<section>
			<h2>申し訳ございません。障害が発生しました。</h2>
			<p>{{errorMsg}}</p>
		</section>
	</body>
</html>

エラーレンダラクラスの登録

 前項で完成したエラーレンダラクラスを使って、実際に独自エラー画面を表示させるようにしましょう。そのためには、エラーミドルウェアにエラーレンダラクラスを登録する必要があります。それは、リスト1の(2)の続きとしてリスト4の(3)と(4)の2行を追記することです。

[リスト4]firstslim/src/public/index.php
〜省略〜
$app = AppFactory::create();

$app->addRoutingMiddleware();  // (1)
$errorMiddleware = $app->addErrorMiddleware(true, true, true);  // (2)
$errorHandler = $errorMiddleware->getDefaultErrorHandler();  // (3)
$errorHandler->registerErrorRenderer("text/html", CustomErrorRenderer::class);  // (4)

$app->setBasePath("/firstslim/src/public");
〜省略〜

 エラーレンダラクラスの登録は、エラーハンドラインスタンスに対して行います。そのため、(2)のエラーミドルウェアインスタンスである$errorMiddlewareから、getDefaultErrorHandler()メソッドを使ってエラーハンドラインスタンスを取得します。それが、リスト4の(3)です。

 その戻り値であるエラーハンドラインスタンス$errorHandlerのメソッドregisterErrorRenderer()を使ってリスト2のエラーレンダラクラスを登録します。その際、第1引数としてエラーが発生したリクエストのコンテントタイプを、第2引数としてエラーレンダラクラスそのものを指定します。それがリスト4の(4)です。

 ここでは画面表示を前提としているので、コンテントタイプとしてtext/htmlを指定し、エラーレンダラクラスとしてリスト2で作成したCustomErrorRendererを指定しています。ただし、クラスそのものの指定なので、CustomErrorRenderer::classという記述になります。

 この状態で、これまでと同じエラーを発生させた場合、図4の画面になります。

図4: 独自のエラー画面が表示された画面
図4: 独自のエラー画面が表示された画面

 無事、エラー画面のカスタマイズが完了したことになります。

次のページ
さまざまなパターンに対応させたエラーレンダラクラス

この記事は参考になりましたか?

軽量PHPフレームワークSlimを習得しよう連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 齊藤 新三(サイトウ シンゾウ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook <個人紹介>WINGSプロジェクト所属のテクニカルライター。Web系製作会社のシステム部門、SI会社を経てフリーランスとして独立。屋号はSarva(サルヴァ)。HAL大阪の非常勤講師を兼務。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/12397 2020/06/18 11:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー