SHOEISHA iD

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

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

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

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

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

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

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

 前節でエラー画面表示のカスタマイズが一通り完了しました。ここからは、さらにさまざまなパターンに対応させたカスタマイズの方法を紹介していきます。

デフォルトのレンダラクラスとの組み合わせ

 前節で用意したerror.htmlはあくまでサンプルですが、これをきっちりデザインした画面とすることで、アプリのユーザーに対して失礼のないエラー表示となります。一方で、アプリの開発段階では、デザインされた本番向けエラー画面よりも、エラー内容が詳細に表示された図2の方が助かります。そこで、本運用環境では独自のエラー画面を表示させ、開発段階ではSlimデフォルトのエラー画面を表示させるようにCustomErrorRendererクラスを改造します。

 その際、考え方の中心となるのは、__invoke()メソッドの第2引数の$displayErrorDetailsの値です。この値は先述の通り、addErrorMiddleware()の第1引数の値がそのまま渡ってくることになっており、この値こそ、開発環境と本運用環境の切り替えのための値でした。そこで、リスト5のように、__invoke()メソッド内で$displayErrorDetailsの値で分岐を行います。

[リスト5]firstslim/src/classes/exceptions/CustomErrorRenderer.php
<?php
〜省略〜
use Slim\Error\Renderers\HtmlErrorRenderer;  // (1)

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

 $displayErrorDetailsの値で分岐を行っているのがリスト5の(2)です。ifブロック内に詳細エラーを表示させる処理を記述し、elseブロック内に本運用環境の独自エラー画面を表示させる処理を記述します。そのため、elseブロック内のコードはリスト2と同じです。

 一方、ifブロック内の(3)と(4)がSlimのデフォルトエラーレンダラクラスを利用した処理です。Slimのデフォルトエラーレンダラクラスというのは、\Slim\Error\Renderers\HtmlErrorRendererです。このインスタンスを生成しているのが(3)です。ただし、このクラスを利用するために(1)のように事前にuseしておく必要があります。

 HtmlErrorRendererクラスも、そのレンダリング処理は__invoke()メソッドに記述されているので、newしたインスタンス$htmlErrorRendererに対して関数のように呼び出すだけで、デフォルトのエラー画面HTML文字列を生成してくれます。それが(4)です。引数は、__invoke()の引数と同じなので、そのまま渡します。

 この状態でエラーを発生させると、無事、図2の画面が表示されます。一方、addErrorMiddleware()の第1引数をfalseとすると図4が表示され、開発環境用、本運用環境用独自エラー画面の2種のエラー画面を、addErrorMiddleware()の第1引数の値で切り替えられるようになりました。

例外ごとに表示画面を切り替える

 今度は、__invoke()メソッドの第1引数を利用してエラー画面を切り替える方法を紹介します。現状で、addErrorMiddleware()の第1引数がtrueの状態で存在しないURLにアクセスした場合、図5の画面が表示されます。

図5: 404エラーの場合の画面
図5: 404エラーの場合の画面

 存在しないURLなので、いわゆる404エラーです。これが、addErrorMiddleware()の第1引数がfalse、つまり、本運用環境の場合、図4が表示されてしまいます。この場合、障害とは言いにくく、エラー画面もそれ専用に変えるべきです。その画面用テンプレートファイルを404.htmlとするならば、404エラーではこの404.htmlを表示させるようにCustomErrorRendererを改造する必要があります。それは、リスト6の通りになります。

[リスト6]firstslim/src/classes/exceptions/CustomErrorRenderer.php
<?php
〜省略〜
use Slim\Exception\HttpNotFoundException;  // (1)

class CustomErrorRenderer implements ErrorRendererInterface
{
	〜省略〜
		else {
			$twig = $this->container->get("view");
			if($exception instanceof HttpNotFoundException) {  // (2)
				$returnHtml = $twig->fetch("404.html");
			}
			else {
				$assign["errorMsg"] = "もう一度初めから操作してください。";
				$returnHtml = $twig->fetch("error.html", $assign);
			}
		}
		return $returnHtml;
	}
}

 図5にもあるように、404エラーは、\Slim\Exception\HttpNotFoundExceptionが発生していることになります。したがって、$displayErrorDetailsの分岐のelseブロック内で、__invoke()の第1引数である$exceptionの型で分岐を行います。先述のように、この$exceptionには、発生した例外インスタンスが渡ってくるので、そのインスタンスの型がHttpNotFoundExceptionと一致するかの判定を行います。それがリスト6の(2)です。そして、一致する場合は、fetch()するテンプレートファイルを404.htmlにします。ただし、そのためには(1)の通り、事前にこのHttpNotFoundExceptionクラスをuseしておいてください。

 この方式を応用して、例えば、以下のようにelseifブロックを積み重ねることで、発生するさまざまな例外に合わせて、表示するエラー画面を適宜切り替えることが可能となります。

if($exception instanceof HttpNotFoundException) {
 :
}
elseif($exception instanceof FileIOException) {
 :
}
:

まとめ

 今回は、本運用では欠かすことのできないSlimのエラーハンドラを扱いました。

 これで、連載終了となります。ここまで全9回に渡り、お付き合いいただき、ありがとうございました。Slimは、マイクロフレームワークとうたうだけあって、作りが非常にシンプルにできているうえ、実際のアプリケーション開発には必要十分な機能が備わっています。フルスタックフレームワークに比べて、プログラマーがコーディングしなければならない部分も増えますが、これは逆にプログラマーが自由にコーディングできるようになっているということでもあります。ややこしいところだけをフレームワークに任せて、自由にコーディングできる、それがSlimの魅力だと思います。この連載で、その魅力の一端でも分かっていただけたら、こんなにうれしいことはありません。

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

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
軽量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」など、さまざまなカンファレンスを企画・運営しています。

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

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

メールバックナンバー