ホームページ  >  記事  >  类库下载  >  PHP エラーと例外の概要

PHP エラーと例外の概要

高洛峰
高洛峰オリジナル
2016-10-20 14:07:171271ブラウズ

エラー

エラーレベル

致命的なエラー: 致命的なエラー(スクリプトの実行が終了します)

E_ERROR 致命的なランタイム致命的なエラー、プログラムの実行を終了します
E_CORE_ERROR 起動時のPHP致命的なエラー
E_COMPILE_ERROR PHPコンパイル中の致命的なエラー
E_USER_ERR またはによって生成された致命的なエラーユーザー

解析エラー: コンパイル中の解析エラー (スクリプトは実行を終了します)

解析エラー コンパイル中の構文解析エラー

警告エラー: 警告エラー (プロンプト情報のみが表示されますが、スクリプトは実行を終了しません。)

E_WARNING 実行時警告 (致命的ではないエラー)。
E_CORE_WARNING PHP の初期化起動時に発生する警告 (致命的ではないエラー)。
E_COMPILE_WARNING コンパイル警告
E_USER_WARNING ユーザー生成の警告情報

Notice Error: 通知エラー (通知情報のみが提供されますが、スクリプトは実行を終了しません。)

E_NOTICE 実行時通知。スクリプトがエラーとして表示される可能性のある状況に遭遇したことを示します。
E_USER_NOTICE ユーザーによって生成された通知情報。

set_error_handler() はエラーをキャプチャします [制限付き]

関数の説明

set_error_handler($callback);//スクリプト内で発生したエラーを処理するためのユーザー関数 (error_handler) を設定します。

関数の制限

次のレベルのエラーは、ユーザー定義関数では処理できません: E_ERROR、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING、および set_error_handler() 関数が呼び出されるファイルで生成されるほとんどの E_STRICT。

つまり: set_error_handler($callback) は、システムによって生成された一部の警告および通知レベルのエラーのみをキャプチャできます。

使用法

<?phpset_error_handler("error_handler");function error_handler($errno,$errstr,$errfile,$errline){    $str=<<<EOF         "errno":$errno
         "errstr":$errstr
         "errfile":$errfile
         "errline":$errlineEOF;
//获取到错误可以自己处理,比如记Log、报警等等    echo $str;
}echo $test;//$test未定义,会报一个notice级别的错误

出力結果:

"errno":8"errstr":Undefined variable: test"errfile":/Users/shuchao/Desktop/handler.php"errline":13
如何捕获PHP的Fatal Error、Parse Error等

要件の説明

PHP の致命的なエラーを取得し、ログに記録するなど、オンラインの問題の分析やオンライン サービスの監視に役立ちます。

2つの関数

register_shutdown_function()

register_shutdown_function($callback)

register_shutdown_function()、登録したい関数を[キューのふり]に入れ、スクリプトが正常に終了するか終了コールが表示されるまで待ちます

register_shutdown_function() が呼び出される場合は、次の 3 つの状況があります。

スクリプトがエラーで終了した場合 (解析時ではなく実行時)。

ユーザー exit メソッドを呼び出して終了する場合。

error_get_last()

error_get_last();//関数は発生した最後のエラーを取得します。

この関数は、最後に発生したエラーを配列の形式で返します。

返された配列には 4 つのキーと値が含まれます:

[type] - エラーの種類

[message] - エラー メッセージ

[file] - エラーが発生したファイル

[line] - エラーが発生した行

メソッド

<?php
register_shutdown_function( "fatal_handler" );
define(&#39;E_FATAL&#39;,  E_ERROR | E_USER_ERROR |  E_CORE_ERROR | 
        E_COMPILE_ERROR | E_RECOVERABLE_ERROR| E_PARSE );function fatal_handler() {  if( $error = error_get_last()) {    $errno   = $error["type"];    $errfile = $error["file"];    $errline = $error["line"];    $errstr  = $error["message"];    $str=<<<EOF         "errno":$errno
         "errstr":$errstr
         "errfile":$errfile
         "errline":$errlineEOF;
//获取到错误可以自己处理,比如记Log、报警等等    echo $str;
  }
}

を使用する

、解析時エラーが発生した場合、 register_shutdown_function() 関数は呼び出されないことに強く注意してください。 Register_shutdown_function() は、実行時エラーが発生した場合にのみ呼び出されます。

以下に例を示します:

NO.1

error_handler.php

<?phpregister_shutdown_function("error_handler");function error_handler(){    echo "Yeah,it&#39;s worked!";
}function test(){}function test(){}

実行結果は次のとおりです:

致命的なエラー: test() を再宣言できません (以前は /Users/shuchao/Desktop/error_handler で宣言されていました) .php:6 ) in/Users/shuchao/Desktop/error_handler.phpの7行目

原因分析

error_handler.phpを実行すると、test()という2つの関数が繰り返し定義されていたため、解析でエラーが発生しましたPHP の -time (実行時ではない) であるため、 register_shutdown_function() の関数をコールバックすることはできません。

NO.2

error_handler.php

<?phpregister_shutdown_function("error_handler");function error_handler(){    echo "Yeah,it&#39;s worked!";
}if(true){   function test(){}
}function test(){}

実行結果は以下の通りです:

Fatal error: Cannot redeclare test() (previously declared in /Users/shuchao/Desktop/error_handler.php:9) in /Users/shuchao/Desktop/error_handler.php on line 7Yeah,it&#39;s worked!%

原因分析

我们看到,上面回调了register_shutdown_function().
因为我们加了一个if()判断,if()里面的test()方法,相当于一个闭包,与外面的test()名称不冲突。
也就是,上面的代码在parse-time没有出错,而是在run-time的时候出错了,所以我们能够获取到fatal error。

NO.3

error_handler.php

<?phpregister_shutdown_function("error_handler");function error_handler(){    echo "Yeah,it&#39;s worked!";}
test_error.php
<?phpinclude &#39;./error_handler.php&#39;;function test(){}function test(){}

执行 test_error.php的结果如下

Fatal error: Cannot redeclare test() (previously declared in /Users/shuchao/Desktop/test_error.php:3) in/Users/shuchao/Desktop/test_error.php on line 4

原因分析

当我们在运行test_error.php的时候,因为redeclare了两个test()方法,所以php的语法解析器在parse-time的时候就出错了。 所以不能回调register_shutdown_function()中的方法,不能catch住这个fatal error。

NO.4

error_handler.php
<?phpregister_shutdown_function("error_handler");function error_handler(){    echo "Yeah,it&#39;s worked!";}
test_error.php
<?phpfunction test(){}function test(){}
include_all.php
require &#39;./error_handler.php&#39;;require &#39;./test_error.php&#39;;

执行 include_all.php的结果如下

Fatal error: Cannot redeclare test() (previously declared in /Users/shuchao/Desktop/include_all.php:2) in /Users/shuchao/Desktop/include_all.php on line 3Yeah,it&#39;s worked!%

结果分析

上面我们捕获了fatal_error.因为在运行include_all.php的时候,include_all.php本身语法并没有出错,也就是在parse-time的时候并没有出错,而是include的文件出错了,也就是在run-time的时候出错了,这个时候是能回调register_shutdown_function()中的函数的。

强烈建议:如果我们要使用register_shutdown_function进行错误捕捉,使用NO.4,最后一种方法,可以确保错误都能捕捉到。

更优美的写法·获取所有错误

set_error_handler()与register_shutdown_function()、error_get_last()的结合使用
<?phpregister_shutdown_function( "fatal_handler" );set_error_handler("error_handler");define(&#39;E_FATAL&#39;,  E_ERROR | E_USER_ERROR |  E_CORE_ERROR |         E_COMPILE_ERROR | E_RECOVERABLE_ERROR| E_PARSE );//获取fatal errorfunction fatal_handler() {    $error = error_get_last();    if($error && ($error["type"]===($error["type"] & E_FATAL))) {        $errno   = $error["type"];        $errfile = $error["file"];        $errline = $error["line"];        $errstr  = $error["message"];        error_handler($errno,$errstr,$errfile,$errline);  }}//获取所有的errorfunction error_handler($errno,$errstr,$errfile,$errline){    $str=<<<EOF         "errno":$errno         "errstr":$errstr         "errfile":$errfile         "errline":$errlineEOF;//获取到错误可以自己处理,比如记Log、报警等等    echo $str;}
Exception
Exception与Error的区别
Exception

当异常抛出的时候,我们是想要去捕获他,并去做处理的。所以异常经常被当做程序的控制流程使用。

Error

Error是不可恢复的,是在开发过程中要去解决的。

使用Exception的例子

我想执行insert语句插入一条数据,可能插入失败(比如ID重复),注意是可能失败,所以这是一个可能的情况,也就是异常情况。我们就可以使用异常来处理这个问题

try {  $row->insert();  $inserted = true;
} catch (Exception $e) {  echo "There was an error inserting the row - ".$e->getMessage();  $inserted = false;
}echo "Some more stuff";

如何catch一个未捕获的Exception

场景描述

假设程序中的有些地方直接throw了异常,没有进行catch。我们现在想要不管在程序的任何一个地方throw异常,即便在throw的地方没有被catch,我们也要能catch住,如何做到呢?

一个函数:set_exception_handler()

//设置默认的异常处理程序,用于没有用 try/catch 块来捕获的异常。 在 exception_handler 调用后异常会中止。

set_exception_handler()

使用示例

1、exception_handler.php
<?phpset_exception_handler("my_exception");function my_exception($exception){    echo $exception->getMessage();}
2、test_exception.php
<?phprequire "./exception_handler.php";throw new Exception("I am Exception");

现在我们运行 test_exception.php,结果如下:

I am Exception //证明我们throw的Exception被捕获了


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

関連記事

続きを見る