エラーハンドラ

エラーハンドラ -- 柔軟なエラーハンドラプラグインシステム

導入

HTML_CSS パッケージには、柔軟なエラーハンドラプラグインシステムが組み込まれており、 お好みのエラーハンドラを使用することができます。 PEAR_Error オブジェクト (デフォルト) 以外にも PEAR_ErrorStack パッケージや その他のエラーハンドラをプラグインすることができます。

何も設定をしなければ、HTML_CSS の API で発生したエラー (普通のエラーや例外) は HTML_CSS_Error オブジェクトを生成して呼び出し元 (ユーザスクリプト) に返します。

ティップ 他の PEAR パッケージが出した PEAR_Error と HTML_CSS のエラーを区別する簡単な方法は HTML_CSS::isError() です。 また、エラーのレベル (警告、エラー、例外) を取得するには HTML_CSS_Error::getLevel() メソッドを使用します。

使い慣れた PEAR のエラー処理用 API も使えます。
<?php
require_once 'HTML/CSS.php';

$css = new HTML_CSS();

$result = $css->setStyle('div', 'color', 5);
if (PEAR::isError($result)) {
    // 何らかのエラー処理
}
?>
出力結果は、このようになるでしょう。

Exception(1): invalid input, parameter #3 "$value" was expecting "string",
instead got "integer"(2) in html_css->setstyle (file [path_to]\[filename] on line 6)(3)
(1)
エラーレベル
(2)
メッセージ本文とコンテキスト情報
(3)
呼び出しコンテキスト

この標準の挙動では不満があるかもしれませんが、心配無用です。 すべてを変更することができます。

重要項目 HTML_CSS は、 display_errors および log_errors のプロトコルに従っています。

ハンドラの設定

エラーハンドラを設定するには、コンストラクタの引数を使用します。 パラメータの概要を、以下に示します。

<?php
require_once 'HTML/CSS.php';

$errorConf = array('error_handler' => 'myErrorHandler',
                   'push_callback' => 'myError',
                   // ... その他のオプション
                  );
$css = new HTML_CSS(null, $errorConf);
?>

表 47-1エラーハンドラの設定パラメータ

オプション説明
error_handlercallback HTML_CSS::raiseError() メソッドが実行するエラー処理用のコールバック (関数)。 デフォルトは HTML_CSS::_errorHandler
push_callbackcallback 以下のアクションを決定するコールバック (関数)。 デフォルトの返り値は、例外の場合は PEAR_ERROR_DIE、 それ以外の場合は NULL
error_callbackcallback 後始末用のユーザ関数をコールすることを決定するコールバック (関数)。 デフォルトは、なし。
message_callbackcallback メッセージの生成を制御するコールバック (関数)。 デフォルトは HTML_CSS_Error::_msgCallback
context_callbackcallback エラーコンテキストの生成を制御するコールバック (関数)。 デフォルトは HTML_CSS_Error::getBacktrace
handlermixed ハンドラ固有の設定。

エラーの発生の制御

より綿密なエラー処理が必要となる場面も多々あります。

エラーの発生を制御する第一段階は、php.ini の設定項目 display_errorslog_errors です。 これらを TRUE にすると、それぞれブラウザ向けとファイル向けの出力が有効になります。

ティップ すべてのエラーを無視したい (画面にもログファイルにも出力しない)、 そして PEAR のコアクラスをインクルードせずに済ませたいという場合は、 このように設定します。
<?php
require_once 'HTML/CSS.php';

function myErrorHandler()
{
    return null;
}

$errorConf = array('error_handler' => 'myErrorHandler');
$css = new HTML_CSS(null, $errorConf);
// ...
?>

HTML_CSS 1.4.0 以降のユーザ向けの注意 エラーを画面に出力するかどうか、そしてログファイルに記録するかどうかを、 HTML_CSS の関数コールで設定することもできます。
<?php
require_once 'HTML/CSS.php';

function myErrorAction($css_error)
{
    // $css_error は HTML_CSS_Error オブジェクトのインスタンスです。
    // これを画面に表示するなりログに記録するなりお好みの処理をします。
}

$errorConf = array('error_callback' => 'myErrorAction');
$css = new HTML_CSS(null, $errorConf);
// ...
?>
あるいは、PEAR そのもののエラーハンドラ (PEAR::setErrorHandling, PEAR::pushErrorHandling, PEAR::popErrorHandling) を利用することもできます。
<?php
require_once 'HTML/CSS.php';

function myErrorAction($css_error)
{
    // $css_error は HTML_CSS_Error オブジェクトのインスタンスです。
    // これを画面に表示するなりログに記録するなりお好みの処理をします。
}

PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'myErrorAction');

$css = new HTML_CSS();
// ...
?>

オプション push_callback を指定すると、 スクリプトの実行を停止する (例外の場合はデフォルトでこうなります: 定数 PEAR_ERROR_DIE を返します) かフィルタリングなしで続行する (NULL を返します) かどうかを決められます。

独自のコールバック関数を push_callback に指定する場合、その関数は 2 つの引数をとるものでなければなりません。 最初の引数はエラーコード、次の引数がエラーレベルとなります。 フィルタリングに必要な情報はこれらだけです。 以下の例は、スクリプトで引数の型を間違えた場合の処理を示すものです。
<?php
require_once 'HTML/CSS.php';

function myErrorFilter($code, $level)
{
    if ($code === HTML_CSS_ERROR_INVALID_INPUT) {
        error_log('script: '.__FILE__.' used wrong argument data type', 1, 'admin@yoursite.com');
    }
    return null;
}

$errorConf = array('push_callback' => 'myErrorFilter');
$css = new HTML_CSS(null, $errorConf);
// ...
?>

エラーコンテキストの表示

場合によっては生成されるエラーの内容をカスタマイズしたくなるかもしれません。 たとえば、個々のエラー (普通のエラー/例外) に対して発生時のファイル名や行番号、 クラスや関数といった情報を含めると便利でしょう。 たいていはデフォルトのオプションで十分でしょうが、 コンテキスト情報の出力フォーマットを変更したくなるかもしれません。

この例では、画面表示とログ出力の内容を変更します。
<?php
require_once 'HTML/CSS.php';

$displayConfig = array(
    'lineFormat' => '<b>%1$s</b>: %2$s<br />%3$s',
    'contextFormat' =>   '<b>ファイル名:</b> %1$s <br />'
                       . '<b>行番号:</b> %2$s <br />'
                       . '<b>関数名:</b> %3$s '
);
$logConfig = array(
    'lineFormat' => '%1$s %2$s [%3$s] %4$s',
    'timeFormat' => '%b'
);

$prefs = array(
    'handler' => array('display' => $displayConfig,
                       'log'     => $logConfig
));

$css = new HTML_CSS(null, $prefs);
// ...
$result = $css->setStyle('div', 'color', 5);
?>

画面表示の内容は、次のようになります。

Exception(1): invalid input, parameter #3 "$value" was expecting "string", instead got "integer"(2)
ファイル名: [path_to]\[filename] (3)
行番号: 22 
関数名: html_css->setstyle 
(1)
エラーレベル
(2)
メッセージ本文とコンテキスト情報
(3)
呼び出しコンテキスト (ファイル、行番号、関数)

ログの出力内容は、このようになります。

Jun 127.0.0.1(1) [exception(2)] invalid input, parameter #3 "$value" was expecting "string", instead got "integer"(3)
(1)
クライアントの IP アドレスと実行日
(2)
エラーレベル
(3)
メッセージ本文とコンテキスト情報

注意 画面出力やログ出力をするには、それぞれ php.inidisplay_errorslog_errorsTRUE になっていなければなりません。

では、この結果をどのようにして得たのかを順を追ってみていきましょう。

デフォルトのクラスには、ふたつのドライバ displaylog があることを覚えておきましょう。これらにはそれぞれ独自の設定パラメータがあります。 これらのパラメータの値を書き換えるには、HTML_CSS クラスのコンストラクタの 2 番目の引数で指定するハッシュの handler エントリを使用します。

それを行っているのが、変数 $prefs です。 この変数は 2 つのキーを持つ連想配列で、最初のキー display で表示用ドライバの値、2 番目のキー log でログ出力用のドライバの値を設定します。

では、display ドライバの設定を見てみましょう。 ここで再定義しているのは lineFormat, contextFormat の 2 つだけです。つまり、残りのキーである eol についてはデフォルト値をそのまま使用するということです。以下の表を参照ください。

表 47-2表示用ドライバの設定パラメータ

パラメータデフォルト説明
eolstring<br />\n行末文字シーケンス
lineFormatstring<b>%1$s</b>: %2$s %3$sログに記録するフォーマットの指定:

  • 1$ = エラーレベル

  • 2$ = エラーメッセージ (本文)

  • 3$ = エラーコンテキスト

contextFormatstring in <b>%3$s</b> (file <b>%1$s</b> on line <b>%2$s</b>) コンテキストのフォーマット (クラス、ファイル、行番号) の指定:

  • 1$ = スクリプトのファイル名

  • 2$ = スクリプトファイルの行番号

  • 3$ = クラス/メソッド名

ティップ エラーメッセージにコンテキスト情報を表示させたくない場合は、 lineFormat オプションのパラメータ %3$ を削除しましょう。そうすれば、 contextFormat が設定されていても表示されません。

では、次に log ドライバの独自設定を見てみましょう。 ここで再定義しているのは lineFormat, timeFormat の 2 つだけなので、残りの 6 つのキー eol, contextFormat, ident, message_type, destination, extra_headers についてはデフォルト値をそのまま使用します。以下の表を参照ください。

表 47-3ログ出力用ドライバの設定パラメータ

パラメータデフォルト説明
eolstring\n行末文字シーケンス
lineFormatstring%1$s %2$s [%3$s] %4$s %5$s ログに記録するフォーマットの指定:

  • 1$ = エラー発生時刻

  • 2$ = ident (クライアントの IP アドレス)

  • 3$ = エラーレベル

  • 4$ = エラーメッセージ (本文)

  • 5$ = エラーコンテキスト

contextFormatstringin %3$s (file %1$s on line %2$s) コンテキストのフォーマット (クラス、ファイル、行番号) の指定:

  • 1$ = スクリプトのファイル名

  • 2$ = スクリプトファイルの行番号

  • 3$ = クラス/メソッド名

timeFormatstring%b %d %H:%M:%S strftime が使用するタイムスタンプのフォーマット
identstringREMOTE_ADDR クライアントの IP アドレス
message_typestring3 error_log が使用する出力先の形式
destinationstringhtml_css_error.log error_log が使用する出力先の名前
extra_headersstringNULL 出力先の形式に依存する追加ヘッダ

ティップ エラーメッセージにコンテキスト情報を表示させたくない場合は、 lineFormat オプションのパラメータ %5$ を削除しましょう。そうすれば、 contextFormat が設定されていても表示されません。

独自のエラーメッセージの生成

HTML_CSS_Error には、 エラーメッセージを効率よく生成するためのメソッドが 2 つ用意されています。 これらを使用するには、以下のオプションを HTML_CSS クラスのコンストラクタ (2 番目の引数) で指定する必要があります。

オプション: message_callback

デフォルトのメッセージ処理コールバック (HTML_CSS_Error::_getErrorMessage) は、エラーコードとエラーメッセージテンプレートを対応させた 次のような配列を受け取ります。
<?php
$messages = array(
    HTML_CSS_ERROR_UNKNOWN =>
        'unknown error',
    HTML_CSS_ERROR_INVALID_INPUT =>
        'invalid input, parameter #%paramnum% '
      . '"%var%" was expecting '
      . '"%expected%", instead got "%was%"'
);
?>
基本的に、パーセント記号 (%) で囲まれている変数名は 連想配列の値で置き換えられます。

オプション: context_callback

デフォルトのコンテキスト処理コールバック (HTML_CSS_Error::getBackTrace) は、実行した関数の配列を受け取ってエラーが発生した位置を見つけます。