業務アプリ開発講座

基本的なエラー処理

前回までに作成した関数navHeader()にエラー処理を追記します。

何かしらの理由で指定してファイルを読みこなかったり、読み込んだJSONファイルがカンマが抜けていたりして正しくなかったりした場合、メニュータグを生成できません。また、システム的なエラー内容をユーザーに見せてしまうことも好ましくありません。とは言っても開発中はエラーが発生したら即座に知りたいものです。

エラー処理は、どのレベルまでプログラミングするかはシステムの要件によって違ってきます。例えば、データベースにアクセスできないようなことが起こった場合は、データベースにアクセスできるようにメンテナンスしない限り、それ以上アプリケーションを実行できませんし、入力不正くらいでしたら、ユーザーにメッセージを表示して正しく入力してもらうよう伝えることで、サービスを続けられます。

また、それらエラーが発生した場合の、次のフローをどうするかはシステムごとに違ってきます。
プログラミング言語には、様々なエラー処理方法は用意されていて、適宜使い分けながら構築していきます。
今回は、エラー処理をどうプログラミングするかをイメージできる程度のシンプルなものを組み込んでみます。講座が進む過程で適宜、様々なエラー処理を紹介していきます。

まず、sitemap.jsonを読み込む際にエラーが発生した場合の書き方です。

$sitemap= file_get_contents('../app-data/sitemap.json');

上記ソースを下記に書き換えます。

if(!$sitemap = @file_get_contents('../app-data/sitemap.json')){
	errorLog(error_get_last());
	return;
}
@file_get_contents()

何やら頭に@が付いています。これはエラー制御演算子と言って、関数等の頭に@をつけるとエラーメッセージを無視するというものです。正しくファイルを読み込めればその内容が、失敗すればfalseが帰ってきます。その結果を変数$sitemapに代入しています。さらにその変数$sitemapの前に!エクスクラメーションマークをつけることで、変数$sitemapの値がfalseだったらという意味になります。ですので、この条件ブロックでは、jsonファイルの読み込みに失敗したら、関数errorLog()を呼び題して、ここで、処理を中断しています。

関数errorLog()はまだ作成していません。あとで、作成します。

error_get_last()

この関数はPHPの組み込み関数で、直前のエラー情報を取得します。ですので、file_get_contents()でエラーが発生した場合、そのエラー情報をこのerro_get_last()関数を使用して取得することができるのです。値は連想配列で返ってきます。エラー情報取得関数は様々なものが組み込まれていて、その内容も様々です。json_decode()のところでもう一つ紹介します。

さて、関数erroLog()を新規に作成します。とりあえず、AppMasterHtml.phpの関数navHeader()の下に作成します。

function navHeader(){
}
function erroLog($err){
	$errContents= '';
	if(is_array($err)){
		$errItems	= [];
		foreach($err as $key => $value){
			$errItems[]	= "[{$key}] {$value}";
		}
		$errContents	= implode("\n", $errItems);
	}
	else{
		$errContents = $err;
	}
	$date		= date('Ymd');
	$datetime	= date('y-m-d h:i:s');
	$msg		= <<<DOC
---- [{$datetime}] ------------------------------------------
{$errContents}\n
DOC;

	$displayError	= false;
	if($displayError){
		echo "<pre>{$msg}</pre>";
	}
	else{
		error_log($msg, 3, "../log/error-{$date}.log");
	}
}

引数の$errには、エラーの種類によって文字列だったり、連想配列だったりします。ですので、関数is_array()を使って引数が配列かどうかで、処理を振り分けます。配列だった場合、その要素を全て連結してエラーメッセージ文字列を生成します。

変数$dateはエラーログファイル名に使用します。エラーログファイルを日付単位で作成しようというわけです。ログファイルの分け方は、今回のように日付単位やバイト数単位などプロジェクトごとに違ってくるでしょう。気をつけなければならないのは、ファイルが大きくなりすぎないように見極めることです。そうしないとエラーログファイルに書き込めなくなって、それが原因でシステムがフリーズしています可能性があるからです。

変数$datetimeはエラーの発生した日時として使用します。ミリ秒まで含めるかどうかはそのシステム次第です。ここではミリ秒までは含めないものとします。

変数$msgでメッセージを生成しています。ヒアドキュメント方式を使用して、メッセージを整形しています。

最後のブロックは、画面にエラー内容を表示するかしないかで処理を振り分けています。画面にエラーを表示しない場合は、エラーログファイルにその内容を書き込んでいます。

最後にjson_decode()にエラー条件を追加しましょう。

if(!$navData = json_decode($encoded, false)){
	errorLog(json_last_error_msg());
	return;
}

json_decode()の場合、エラー情報を取得する関数が異なります。連想配列ではなく、簡単な一言メッセージを返すだけです。

基本的なエラー処理を示しました。
次回はこれまで作成した、ソースを整理したいと思います。