PHP エラーハンドリング

PHPでは、デフォルトのエラーハンドリングは非常に簡単です。メッセージがブラウザに送信され、そのメッセージにはファイル名、行番号、エラーメッセージが含まれています。

PHP エラーハンドリング

スクリプトやウェブアプリケーションを作成する際には、エラーハンドリングは重要な部分です。もしコードにエラーデテクションのコーディングが不足していると、プロフェッショナルな見た目を欠き、セキュリティリスクを増大させます。

このチュートリアルでは、PHPで最も重要なエラーデテクション方法について紹介しています。

私たちは、異なるエラーハンドリング方法について説明します:

  • シンプルな"die()"文
  • カスタムエラーとエラートリガー
  • エラーレポート

基本的なエラーハンドリング:die()関数の使用

以下の例では、テキストファイルをオープンするシンプルなスクリプトを示します:

<?php
$file=fopen("welcome.txt","r");
?>

ファイルが存在しない場合、このようなエラーを受け取ります:

警告: fopen(welcome.txt) [function.fopen]: ストリームをオープンするに失敗しました: 
ファイルまたはディレクトリが見つかりません C:\webfolder\test.php2

上記のようなエラーメッセージを受け取らないように、ファイルにアクセスする前にそのファイルが存在するかどうかを確認します:

<?php
if(!file_exists("welcome.txt"))
 {
 die("File not found");
 }
else
 {
 $file=fopen("welcome.txt","r");
 }
?>

今、ファイルが存在しない場合、このようなエラーメッセージを受け取ります:

ファイルが見つかりません

前のコードよりも、上のコードはより効果的です。なぜなら、エラーの後でスクリプトを終了するシンプルなエラーハンドリングメカニズムを使用しているからです。

ただ、スクリプトを単純に終了することは常に適切な方法ではありません。エラーを処理するためのPHP関数の代替手段を研究しましょう。

カスタムエラーハンドラの作成

カスタムのエラーハンドラを設定するのは非常に簡単です。私たちは、PHPでエラーが発生したときに呼び出せる専用の関数を簡単に作成しました。

この関数は少なくとも2つのパラメータ(エラーレベルとエラーメッセージ)を処理する能力を持たなければなりませんが、最も多く5つのパラメータ(オプション:ファイル、行番号およびエラーコンテキスト)を受け入れることができます:

構文

error_function(error_level, error_message,
error_file, error_line, error_context)
パラメータ 説明
error_level

必要です。ユーザー定義のエラーレポートレベルを定義します。数値の値を持たなければなりません。

以下のテーブルを参照してください:エラーレポートレベル。

error_message 必要です。ユーザー定義のエラーレポートを定義するエラーメッセージです。
error_file オプション。エラーが発生したファイル名を指定します。
error_line オプション。エラーが発生した行番号を指定します。
error_context オプション。エラーが発生した際に使用されている各変数とその値を含む配列を指定します。

エラーレポートレベル

これらのエラーレポートレベルは、エラーハンドラが処理するエラーの異なるタイプです:

定数 説明
2 E_WARNING 致命的なランタイムエラーではありません。スクリプトの実行を停止しません。
8 E_NOTICE

ランタイム通知

スクリプトがエラーが発生する可能性があると認識していますが、スクリプトが通常通りに実行されている場合もあります。

256 E_USER_ERROR 致命的なユーザーが生成したエラー。プログラマーがPHP関数trigger_error()を使用して設定したE_ERRORに似ています。
512 E_USER_WARNING 致命的なユーザーが生成した警告。プログラマーがPHP関数trigger_error()を使用して設定したE_WARNINGに似ています。
1024 E_USER_NOTICE ユーザーが生成した通知。プログラマーがPHP関数trigger_error()を使用して設定したE_NOTICEに似ています。
4096 E_RECOVERABLE_ERROR キャプチャ可能な致命的なエラー。E_ERRORに似ていますが、ユーザー定義のハンドラでキャプチャできます。(set_error_handler()を参照)
8191 E_ALL

すべてのエラーと警告、E_STRICTレベルを除きます。

(PHP 6.0では、E_STRICTはE_ALLの一部です)

エラーハンドリングを行う関数を作成しましょう:

function customError($errno, $errstr)
 { 
 echo "<b>エラー:</b> [$errno] $errstr<br />";
 echo "スクリプト終了";
 die();
 }

上記のコードはシンプルなエラーハンドラ関数です。トリガーされた場合、エラーレベルとエラーメッセージを取得します。それから、エラーレベルとメッセージを出力し、スクリプトを終了します。

現在、エラーハンドラ関数を作成しましたが、その関数がどのタイミングでトリガーされるかを決定する必要があります。

エラー処理ハンドラの設定

PHPのデフォルトのエラーハンドラは内蔵のエラーハンドラです。上記の関数をスクリプト実行中のデフォルトのエラーハンドラとして改造することを目指しています。

エラーハンドラを変更して、特定のエラーにのみ適用することで、スクリプトは異なる方法で異なるエラーを処理できます。ただし、この例では、すべてのエラーに対してカスタムエラーハンドラを使用することを目指しています:

set_error_handler("customError");

私たちのカスタム関数がすべてのエラーを処理するように希望するため、set_error_handler() は単一の引数が必要ですが、二つ目の引数を追加してエラーレベルを指定することができます。

存在しない変数を出力することでこのエラーハンドラをテストします:

<?php
//エラーハンドラーファンクション
function customError($errno, $errstr)
 { 
 echo "<b>エラー:</b> [$errno] $errstr";
 }
//エラーハンドラーセット
set_error_handler("customError");
//エラートリガー
echo($test);
?>

上記のコードの输出は以下のようになります:

Error: [8] 未定義の変数: test

エラーをトリガーする

ユーザーがデータを入力するスクリプト内の位置で、ユーザーの入力が無効な場合にエラーをトリガーする非常に便利なものです。PHPでは、このタスクはtrigger_error()によって完了します。

この例では、「test」変数が「1」より大きい場合にエラーが発生します:

<?php
$test=2;
if ($test>1)
{
trigger_error("値は1または以下でなければなりません");
}
?>

上記のコードの输出は以下のようになります:

Notice: 値は1または以下でなければなりません
in C:\webfolder\test.php on line 6

スクリプトのどこでもエラーをトリガーできます。追加の第2引数を使用して、トリガーするエラーレベルを指定できます。

可能なエラータイプ:

  • E_USER_ERROR - 致命なユーザーが生成したランタイムエラー。エラーは復旧できません。スクリプトの実行は中断されます。
  • E_USER_WARNING - 致命でないユーザーが生成したランタイム警告。スクリプトの実行は中断されません。
  • E_USER_NOTICE - デフォルト。ユーザーが生成したランタイム通知。スクリプトが可能性のあるエラーを見つけた場合や、スクリプトが正常に実行されている場合にも発生します。

この例では、「test」変数が「1」より大きい場合にE_USER_WARNINGエラーが発生します。E_USER_WARNINGが発生した場合、カスタムエラーハンドラを使用してスクリプトを終了します:

<?php
//エラーハンドラーファンクション
function customError($errno, $errstr)
 { 
 echo "<b>エラー:</b> [$errno] $errstr<br />";
 echo "スクリプト終了";
 die();
 }
//エラーハンドラーセット
set_error_handler("customError",E_USER_WARNING);
//エラートリガー
$test=2;
if ($test>1)
 {
 trigger_error("値は 1 またはそれ以下でなければなりません",E_USER_WARNING);
 }
?>

上記のコードの输出は以下のようになります:

エラー: [512] 値は 1 またはそれ以下でなければなりません
スクリプト終了

今では、自分自身のerrorを作成する方法や、それをトリガーする方法を学びました。今度はエラーログについて研究しましょう。

エラーログ

デフォルトでは、php.ini内のerror_log設定に基づいて、PHPはエラーログをサーバーのエラーレコードシステムまたはファイルに送信します。error_log()関数を使用することで、指定されたファイルまたはリモート先にエラーログを送信できます。

自分自身にEメールを通じてエラーメッセージを送信することは、特定のエラーを通知するのに良い方法です。

E-Mailを通じてエラーメッセージを送信

以下の例では、特定のエラーが発生した場合、エラーメッセージを含むメールを送信し、スクリプトを終了します:

<?php
//エラーハンドラーファンクション
function customError($errno, $errstr)
 { 
 echo "<b>エラー:</b> [$errno] $errstr<br />";
 echo "Webmaster has been notified";
 error_log("エラー: [$errno] $errstr",1,
 "someone@example.com","From: webmaster@example.com");
}
//エラーハンドラーセット
set_error_handler("customError",E_USER_WARNING);
//エラートリガー
$test=2;
if ($test>1)
 {
 trigger_error("値は 1 またはそれ以下でなければなりません",E_USER_WARNING);
 }
?>

上記のコードの输出は以下のようになります:

エラー: [512] 値は 1 またはそれ以下でなければなりません
ウェブマスターに通知されました

上記のコードから受け取るメールは以下のようになります:

エラー: [512] 値は 1 またはそれ以下でなければなりません

このメソッドはすべてのエラーに適用されるわけではありません。一般的なエラーは、デフォルトの PHP レコードシステムを使用してサーバー上に記録されるべきです。