エラー処理

エラー内容の把握 (error_reporting)

error_reporting()で、出力されるエラーの種類を制御できます。この関数はphp.iniの、error_reportingディレクティブの値を実行時に設定するものです。

int error_reporting ([ int $level ] )
PHP: error_reporting - Manual

$levelは以下のエラーレベル定数より指定します。ここで指定されたエラーだけが、出力されるようになります。なおこの値の既定値は、PHP 4とPHP 5ではE_ALL & ~E_NOTICE (E_ALLからE_NOTICEを除外した値) です。

個々のエラーを細かく制御する必要がないならば、

error_reporting( 0 );

とすることで、すべてのエラー出力を無効にできます。一方で、

error_reporting( E_ALL );

とすると、すべてのエラー出力を有効にできます。

エラーの種類 (error type)

エラーレベルとして、以下の定数が定義されています。

定数 タイミング 種別 説明 備考
1
(0x0001)
E_ERROR 実行時 エラー 重大な実行時エラー。これはメモリ確保に関する問題のように、復帰できないエラーを示す。スクリプトの実行は中断される。  
2
(0x0002)
E_WARNING 実行時 警告 実行時の (致命的なエラーではない) 警告。スクリプトの実行は中断されない。  
4
(0x0004)
E_PARSE コンパイル時 エラー コンパイル時のパースエラー。パースエラーはパーサでのみ生成される。  
8
(0x0008)
E_NOTICE 実行時 警告 実行時の警告。エラーを発しうる状況に遭遇したことを示す。ただし通常のスクリプト実行の場合にも、この警告を発することがありうる。  
16
(0x0010)
E_CORE_ERROR 初期始動時 エラー PHPの初期始動時点での致命的なエラー。 E_ERRORに似るが、PHPのコアによって発行される点が異なる
32
(0x0020)
E_CORE_WARNING 初期始動時 警告 (致命的ではない) 警告。PHPの初期始動時に発生する。 E_WARNINGに似るが、PHPのコアによって発行される点が異なる
64
(0x0040)
E_COMPILE_ERROR コンパイル時 エラー コンパイル時の致命的なエラー。 E_ERRORに似るが、Zendスクリプティングエンジンによって発行される点が異なる
128
(0x0080)
E_COMPILE_WARNING コンパイル時 警告 コンパイル時の (致命的ではない) 警告。 E_WARNINGに似るが、Zendスクリプティングエンジンによって発行される点が異なる
256
(0x0100)
E_USER_ERROR ユーザー エラー ユーザーによって発行されるエラーメッセージ。 E_ERRORに似るが、PHPコード上でtrigger_error()関数を使用した場合に発行される点が異なる
512
(0x0200)
E_USER_WARNING ユーザー 警告 ユーザーによって発行される警告メッセージ。 E_WARNINGに似るが、PHPコード上でtrigger_error()関数を使用した場合に発行される点が異なる
1024
(0x0400)
E_USER_NOTICE ユーザー 注意 ユーザーによって発行される注意メッセージ。 E_NOTICEに似るが、PHPコード上でtrigger_error()関数を使用した場合に発行される点が異なる
2048
(0x0800)
E_STRICT     コードの相互運用性や互換性を維持するために、PHPがコードの変更を提案する。  
4096
(0x1000)
E_RECOVERABLE_ERROR   エラー キャッチできる致命的なエラー。危険なエラーが発生したが、エンジンが不安定な状態になるほどではないことを表す。ユーザー定義のハンドラでエラーがキャッチされなかった場合は、E_ERRORとして異常終了する。  
8192
(0x2000)
E_DEPRECATED 実行時 注意 実行時の注意。これを有効にすると、将来のバージョンで動作しなくなるコードについての警告を受け取ることができる。  
16384
(0x4000)
E_USER_DEPRECATED   警告 ユーザー定義の警告メッセージ。 E_DEPRECATEDに似るが、PHPのコード上で関数trigger_error()によって作成されるという点が異なる。
32767
(0x7FFF) ※1
E_ALL     サポートされる全てのエラーと警告。PHP 5.4.0より前のバージョンでは、E_STRICTレベルのエラーは除く。  
※1
  • PHP 5.4.xでは、32767 (0x7FFF)
  • PHP 5.3.xでは、30719 (0X77FF) … E_STRICTなし
  • PHP 5.2.xでは、6143 (0X17FF) … E_STRICT、E_DEPRECATED、E_USER_DEPRECATEDなし
  • それより前のバージョンでは、2047 (0X07FF)
PHP: 定義済み定数 - Manual

エラーの記録

エラーのログをファイルに記録するには、php.ini

  • log_errors … 1
  • error_log … (エラーを記録するファイル名)

のように、2つのディレクティブを設定します。また必要に応じて、

  • error_reporting
  • display_errors

の2つも設定します。

スクリプトから設定するならば、

error_reporting( E_ALL );
ini_set( 'display_errors', '0' );
ini_set( 'log_errors', '1' );
ini_set( 'error_log', '/home/user/public_html/errors.log' );

のようにします。同様の設定をApacheの設定ファイルからするならば、

php_value error_reporting 30719
php_flag display_errors off
php_flag log_errors on
php_value error_log "/home/user/public_html/errors.log"

とします。[重要]システムエラーの表示について - Geeklog Japanese

error_reporting()で出力されるように設定されていないエラーは、ログにも記録されません。

独自のエラー記録

error_log()を使用すれば、エラーメッセージとエラーの記録先を独自に指定できます。

bool error_log (
    string $message
    [, int $message_type = 0
    [, string $destination
    [, string $extra_headers
    ]]] )
PHP: error_log - Manual

エラーメッセージを$messageで指定します。エラーの記録先は$destinationで、

のいずれかを数値で指定します。これらは、それぞれ

error_log( 'TEST', 0 );                    // 標準のログに記録
error_log( 'TEST', 1, 'foo@example.com' ); // メールで通知
error_log( "TEST\n", 3, 'errors.log' );    // ファイルに記録

のように使用します。

一時的なエラーの抑制

error_reporting()は引数を指定しないときは現在の設定を返すため、これを利用して設定の一部を一時的に変更できます。

たとえば「Deprecated」を一時的に抑制するならば、次のようにします。

$errorLevel = error_reporting();
error_reporting( $errorLevel & ~E_DEPRECATED );

// Deprecatedを発生する処理

error_reporting( $errorLevel );

独自のエラー処理 (set_error_handler)

エラーを、独自に定義したエラーのハンドラ関数で処理します。

mixed set_error_handler (
    callable $error_handler
    [, int $error_types = E_ALL | E_STRICT ]
    )
PHP: set_error_handler - Manual

$error_handlerには、ハンドラ関数の名前を文字列で指定します。

$error_typesに指定したエラーの種類の内、実際にハンドラ関数が呼ばれるのは、次のエラーのみです。

  • E_WARNING
  • E_NOTICE
  • E_USER_ERROR
  • E_USER_WARNING
  • E_USER_NOTICE
  • E_STRICT
  • E_RECOVERABLE_ERROR
  • E_DEPRECATED
  • E_USER_DEPRECATED

以下のエラーでは呼ばれません。

  • E_ERROR … 実行時の重大なエラー
  • E_PARSE … コンパイル時のパースエラー
  • E_CORE_ERROR … PHPの初期始動時のエラー
  • E_CORE_WARNING … PHPの初期始動時の警告
  • E_COMPILE_ERROR … コンパイル時のエラー
  • E_COMPILE_WARNING … コンパイル時の警告

set_error_handlerで、すべての種類のエラーを処理できるわけではありません。

error_reporting()によるエラー出力の抑制は、この関数には無関係です。

ハンドラ関数

エラーを捕捉するハンドラ関数は、次の構文に従う必要があります。

handler (
    int $errno ,
    string $errstr
    [, string $errfile
    [, int $errline
    [, array $errcontext ]]] )
PHP: コールバック - Manual

通常のエラーハンドラにも処理を渡すには、ハンドラ関数からFALSEを返します。

エラー捕捉の例

ゼロ除算で警告を発生させ、それを捕捉してみます。

function handler( $errno, $errstr, $errfile, $errline, $errcontext )
{
    echo <<<EOM
$errno
$errstr
$errfile
$errline
EOM;
    return TRUE;
}

set_error_handler( 'handler' );

$a = 1 / 0;
echo "\n\n OK";

結果は、次のように出力されます。

2
Division by zero
C:\test.php
15

 OK

この警告は、既定では

Warning: Division by zero in C:\test.php on line 15

のように出力されるものです。

独自のエラーの生成

bool trigger_error (
    string $error_msg
    [, int $error_type = E_USER_NOTICE ]
    )
PHP: trigger_error - Manual

たとえば、

trigger_error( 'Foo' );

とすると、

Notice: Foo in C:\sample.php on line 1

のように出力されます。

$error_typeに指定できるのは「E_USER~」の定数だけです。それ以外ではInvalid error type specifiedとなります。

$error_typeの値 種類 出力
無指定 注意 Notice
E_USER_NOTICE
E_USER_WARNING 警告 Warning
E_USER_ERROR エラー Fatal error
E_USER_DEPRECATED 警告 Deprecated

E_USER_ERRORを指定した場合、既定ではスクリプトの実行が中断されます。

サンプルコード

独自のエラーを生成し、それを捕捉してみます。

function handler( $errno, $errstr )
{
    switch( $errno )
    {
        case E_USER_ERROR:
            echo "ERROR: $errstr";
            break;

        case E_USER_WARNING:
            echo "WARNING: $errstr";
            break;
    }
    return TRUE;
}

set_error_handler( 'handler', E_USER_ERROR | E_USER_WARNING );

trigger_error( 'Foo', E_USER_ERROR );   // ERROR: Foo
trigger_error( 'Bar', E_USER_WARNING ); // WARNING: Bar
trigger_error( 'Baz', E_USER_NOTICE );  // Notice: Baz in ...