今回は、例外処理を実装して行きます。画像は特に関係ありません。おそらく見覚えのあり方は若くても30代?
エクセルとか使っているとよく登場しました…。
例外とは…
プログラムの実行時に、何らかの例外的な事象が発生すること。Javaではシステムエラー以外のエラー(実行時例外、入出力例外など)に対して例外処理のクラスが初めから用意されており、例外が発生した場合にはこれらのクラスを呼び出して処理する。(コトバンクより)
Java ではと書いてありますが、PHPでもExceptionクラスを呼び出します。
スローされるオブジェクトは、Exception クラスあるいは Exception のサブクラスのインスタンスでなければなりません。 それ以外のオブジェクトをスローしようとすると PHP の Fatal Error が発生します。
「スローされる」は「発生させる」と置き換えて読むと理解しやすいかもしれません。「サブクラス」とはクラスを継承したクラスのことです。
例外処理を適切にハンドリングしておくと、エラーや不具合の原因追求の手助けとなります。
エラーや不具合は多種多様です。軽微なものであればユーザーに操作のやり直しを促すだけで回避できるものや、プログラム自体の修正をしなければならない重大なものまで存在します。重大なものであれば、発生したと同時に開発者にメールで通知する必要があるかもしれません。
ここでは、軽微な例外と通常の例外と深刻な例外と大きく3つに分けて実装して行きます。
それぞれ名前をつけましょう。
- 深刻な例外: SystemErrorException
- 通常の例外: ApplicationErrorException
- 軽微な例外: InvalidErrorException
それぞれ例外が発生したときに、どのように扱うかをまとめておきます。
クラス名 | ログの書き出し | 画面表示する文言 | 管理者へのメール送信 |
---|---|---|---|
SystemErrorException | する | システムエラーが発生しました | する |
ApplicationErrorException | する | アプリケーションエラーが発生しました | しない |
InvalidErrorException | しない | エラーメッセージをそのまま表示する | しない |
##InvalidErrorExceptionの実装##
commonディレクトリ以下に、InvalidErrorException.class.php を作成します。
#1で説明した様に、namespace をつけて定義します。
<?php
namespace MyApp\common;
class InvalidErrorException extends \Exception
{
public function __construct($code, \Exception $previous = null)
{
parent::__construct($message, $code, $previous);
}
}
ここで、第1引数に $message をつけていないのは、このコードとメッセージをしっかり管理したいので、別のクラスで一元管理したいからです。
同じく、common 以下に ExceptionCode.class.php を作成します。
<?php
namespace MyApp\common;
class ExceptionCode
{
//エラーコードを整数で定義する
const INVALID_ERR = 1000;
//定数をキーに配列でメッセージを定義する
static private $_arrMessage = array(
INVALID_ERR => 'エラーが発生しました。' //とりあえずのメッセージ
);
static public function getMessage($intCode)
{
if (array_key_exists($intCode, self::$_arrMessage)) {
return self::$_arrMessage[$intCode];
}
}
}
メッセージはコンストラクタ内から、コードで呼び出します。
<?php
namespace MyApp\common;
class InvalidErrorException extends \Exception
{
public function __construct($code, \Exception $previous = null)
{
$message = ExceptionCode::getMessage($code);//追記
parent::__construct($message, $code, $previous);
}
}
##SystemErrorExceptionの実装##
基本的には前項のものと同じですが、「メールを送信する」「ログを書く」「表示メッセージは統一する」という点で先ほどとは異なります。
<?php
namespace MyApp\common;
class SystemErrorException extends \Exception
{
/**
* コンストラクタ
* @param type $code
* @param \Exception $previous
*/
public function __construct($code, \Exception $previous = null)
{
$message = ExceptionCode::getMessage($code);
self::writeLog($message);
self::sendMail($message);
parent::__construct('システムエラーが発生しました。', $code, $previous);
}
/**
* 管理者へメール
* @param type $message
*/
static private function sendMail($message)
{
}
/**
* ログを書く
* @param type $message
*/
static private function writeLog($message)
{
}
}
メール送信とログについてはから実装にしておきます。このようにしておけば、要件どおりの動きをすることは理解できますでしょうか。
同様に、ApplicationErrorException も実装して行くと、以下のようになりますね。
<?php
namespace MyApp\common;
class ApplicationErrorException
{
/**
* コンストラクタ
* @param type $code
* @param \Exception $previous
*/
public function __construct($code, \Exception $previous = null)
{
$message = ExceptionCode::getMessage($code);
self::writeLog($message);
parent::__construct('アプリケーションエラーが発生しました。', $code, $previous);
}
/**
* ログを書く
* @param type $message
*/
static private function writeLog($message)
{
}
}
次回はデータベース周りの機能について実装して行きます。