[PHP] エラー出力の制御について
PHPのエラー出力の制御は、php.iniのerror_reportingに設定する方法と、もしくはプログラム実行時に関数で設定する方法があります。
プログラムで設定する場合は、ini_set関数で設定するか、専用のerror_reporting関数で設定する方法があります。
error_reporting関数
error_reporting関数は、引数にエラーの種類を表す定数を指定し、どの種類のエラーを出力するのかを設定することが出来ます。
なお引数の設定値はint型のため数値リテラルを設定することもできますが、組み込み定数を使って指定することが推奨されています。
公式マニュアル: https://www.php.net/manual/ja/function.error-reporting.php
error_reporting関数のシグネチャ
引数 |
int (error_level)
※PHP8.0からnullの指定が可能、nullの場合はデフォルト(32767)が設定され、すべてのエラーを出力する設定になる。 |
---|---|
戻り値 |
int
$error_level引数指定ありの場合は、変更前のエラーレベルを返す。 |
error_levelについて
error_levelはPHPコアに組み込まれており、いつでも利用できます。
E_ERROR (1) | 重大なエラー、復帰不可能なためスクリプトは中断する |
---|---|
E_WARNING (2) | 実行時の警告、スクリプトは続行できる |
E_PARSE (4) | コンパイル時のパースエラー |
E_NOTICE (8) | 実行時の警告、スクリプトは続行できる |
E_ALL (32767) | 全てのエラーを出力する |
0 | 全てのエラーを出力しない、定数は無し |
~0 | 0の反転、すべてのエラーを出力する これは将来的に新たなエラーレベルが追加された場合でもカバーできるように用意されている指定方法で、-1を指定しても同じ効果がある |
複数エラーレベルの指定方法
各定数はビット演算子を使って複数指定できます。
例)E_ERRORとE_WARNINGを出力する
error_reporting(E_ERROR | E_WARNING);
例)E_NOTICE以外の全てのエラーを出力する
error_reporting(E_ALL & ~E_NOTICE);
E_ERROR
E_ERRORを設定すると、続行不可能なエラーが発生した場合、Fatal errorが出力されます。
コード
以下の例では、0による除算を行いFatal errorが発生します。
error_reporting(E_ERROR);
echo "error_reporting = ", error_reporting(), "\n";
$var = 10 / 0;
echo "var = ", $var, "\n";
実行結果
$ php test_error.php error_reporting = 1 Fatal error: Uncaught DivisionByZeroError: Division by zero in .\test_error.php:6 Stack trace: #0 {main} thrown in .\test_error.php on line 6
E_WARNING
E_WARNINGを設定すると、警告発生時にWarningを出力します。
コード
以下の例では、未定義の変数$xと$yを使って処理をしていますが、この場合は警告(Warning)が発生します。
error_reporting(E_WARNING);
echo "error_reporting = ", error_reporting(), "\n";
$var = $x + $y;
echo "var = ", $var, "\n";
実行結果
実行結果を確認すると、警告(Warning)は発生しますが、処理は続行し最終的に「var = 0」を出力しているのが分かります。
$ php test_error.php error_reporting = 2 Warning: Undefined variable $x in .\test_error.php on line 6 Warning: Undefined variable $y in .\test_error.php on line 6 var = 0
E_PARSE
E_PARSEに関しては構文エラーを指し、このエラーに関してはスクリプトを読み込んだ時点でチェックされ、エラーを検知するとスクリプトは何も実行されません。したがってerror_reporting関数による抑止はできません。
コード
以下の例では最後のechoの文で構文エラーになっていて、実行するとParse errorが発生します。
//error_reporting(E_PARSE);
echo "error_reporting = ", error_reporting(), "\n";
$var = "E_PARSE";
echo "TEST" $var, "\n";
実行結果
$ php test_error.php Parse error: syntax error, unexpected variable "$var", expecting "," or ";" in .\test_error.php on line 7
E_NOTICE
PHP 8系からエラーレベルが見直され全体的に厳しくなりました。7系以前でE_NOTICEだったものはE_WARNINGへ、E_WARNINGだったものはE_ERRORへと変更されています。
set_error_handler関数
set_error_handler関数を使うと、実行時に発生するエラーをユーザー定義関数(callable型)で制御することが出来ます。
set_error_handler関数の引数について
第一引数 |
callable $callback
callable型のcallback関数を指定し、この中にエラー発生時の制御を記述する |
---|---|
第二引数 |
int $error_levels
ハンドリング対象とするエラーレベルを定数で指定する。この引数は任意で、省略した場合E_ALLとなり、すべてのエラーがハンドリング対象となる。 |
set_error_handler関数に指定するcallback関数について
callback関数は引数を4つ指定して定義します。この関数が呼ばれる際、引数にエラー情報が入ってきますのでそれらを使用し、独自の制御を入れてエラーを制御することが出来ます。
第一引数 |
int $errno
エラーレベル |
---|---|
第二引数 |
string $errstr
エラーメッセージ |
第三引数 |
string $errfile
エラーが発生したPHPファイルのファイルパス |
第四引数 |
int $errline
エラーが発生した行番号 |
[実装例]エラー発生時に独自の例外をスローする
コード
以下の例ではすべてのエラーをハンドリングし、独自の例外をスローする例です。コールバック関数内では引数で渡ってくるエラー情報を出力しています。
class TestException extends Exception {}
set_error_handler(
function ($errno, $errstr, $errfile, $errline) {
echo "errno = ", $errno, "\n";
echo "errstr = ", $errstr, "\n";
echo "errfile = ", $errfile, "\n";
echo "errline = ", $errline, "\n";
echo "--------------------\n";
throw new TestException("[TEST]" . $errstr, 123);
}
);
try {
$i++;
} catch(Exception $e) {
echo "Error No = ", $e->getCode(), "\n";
echo "Exception = ", get_class($e), "\n";
echo $e->getMessage() , "\n";
}
実行結果
実行結果を確認すると、まずエラーがコールバック関数によりハンドリングされて、スローしたTestExceptionはエラーが発生したtry-catch内で補足されていることが分かります。
$ php test_error.php errno = 2 errstr = Undefined variable $i errfile = .\test_error.php errline = 16 -------------------- Error No = 123 Exception = TestException [TEST]Undefined variable $i
ThrowableインターフェースとErrorクラスについて
Throwableインターフェース
PHP7で導入された全てのスロー可能なオブジェクトの基底インターフェースです。ExceptionクラスやErrorクラスもこれを実装しています。
ユーザー定義のクラスがThrowableインターフェースを直接実装することはできません。独自の例外を作る場合は、ExceptionクラスかErrorクラスを継承します。
Errorクラス
Errorクラスは、PHP実行時に発生する全ての内部エラーの基底クラスです。Exceptionクラスとの違いは、プログラムで対処できるかどうかであり、後続処理を続行できない致命的なエラーがErrorクラスとなります。
Throwableインターフェースを実装したクラスの関連図
[実装例]独自エラーを発生させてThrowableインターフェースでキャッチする
コード
class TestError extends Error {}
try {
throw new TestError('Error');
} catch(Throwable $e) {
echo 'catch ', get_class($e), "\n";
echo $e->getMessage(), "\n";
}
実行結果
$ php test_error.php catch TestError Error
コメント
コメントを投稿