PHP의 예외 및 오류 처리기에 대한 세부 정보 및 예

풀어 주다: 2023-04-07 07:46:01
앞으로
3126명이 탐색했습니다.

머리말

최근 프로젝트에서 구현해야 할 기능이 있습니다. 디버깅 모드에서는 모든 오류가 미리 출력된 다음 페이지 내용이 출력됩니다.

위 기능을 구현하려면 Exception 및 Error 관련 Handler 메소드를 사용하기 위해서는 함정이 많다고 판단되어 여러분과 공유하고자 이 글을 작성했습니다.

추천 PHP 동영상 튜토리얼:https://www.php.cn/course/ list/29/type/2.html

주요 함수

이 문서에서는 다음 함수에 중점을 둡니다

1, error_reporting()error_reporting()

2、set_error_handler()

3、set_exception_handler()

4、register_shutdown_function()

5、error_get_last()

以下本文中重点讲解问题列表:

1、error_reporting()  error_get_last() 有什么联系?

2、set_error_handler() 与 set_exception_handler() 绑定的handler什么时候才会启动? 它们有什么联系?

3、register_shutdown_function()通常跟Exception/Error有关系么?

解疑:

1. error_reporting() 与 error_get_last() 有什么联系?

link: php.net - error_reporting()
link: php.net - error_get_last()

a:int error_reporting ([ int $level ] )

大家应该再熟悉不过了, 因此不再赘述.

b:array error_get_last ( void )

获取最后发生的错误

通常用来获取PHP运行过程中的Fatal Error错误(PHP 5).

这两个函数在字面上关联性并不强, 但请观察以下代码及输出

<?php
error_reporting(E_ALL & ~E_NOTICE);
$a = $b;  //E_NOTICEprint_r(error_get_last());/* output:
Array
(
    [type] => 8
    [message] => Undefined variable: b
    [file] => /app/t.php
    [line] => 3
)
*/
로그인 후 복사

error_get_last()虽然说明了获取最后发生的错误, 实际上也是如此. 但却没有说明, 被error_reporting()忽略掉的错误是否有可能被获取到, 因此, 当我们使用error_get_last()时需要注意平时忽略掉的错误, 如: E_DEPRECATED

2. set_error_handler()set_exception_handler() 绑定的handler什么时候才会启动? 它们有什么联系?

link: php.net - set_error_handler()<br/>link: php.net - set_exception_handler()

a、mixed set_error_handler ( callable $error_handler [, int $error_types = E_ALL | E_STRICT ] )

设置用户自定义的错误处理函数<br/>

通常在PHP脚本运行过程中, 出现一些非中断性错误时触发.<br/>我们会用这个来记录错误日志或直接输出等操作.

注意:

FALSE: 标准的错误处理依然会被执行(标准错误处理根据 display_errors = true/false 决定是否输出到stderr)

1、参数$error_types大多设定为error_reporting(), 但建议设定为E_ALL

2, set_error_handler( )🎜🎜3, set_Exception_handler()🎜 🎜4. register_shutdown_function()🎜🎜5.error_get_last()🎜🎜 다음 문서는 문제 목록에 중점을 둡니다. 🎜🎜1. error_reporting() error_get_last() 와의 연결은 무엇입니까? 🎜🎜2. /code>는 handler에 의해 set_Exception_handler()에 바인딩됩니다. code>는 언제 시작되나요? 🎜🎜3. code>는 일반적으로 Exception/Error와 관련이 있습니까? 🎜🎜🎜질문 해결: 🎜🎜

1. error_reporting() 사이의 연결은 무엇입니까? 및 error_get_last()?🎜🎜링크: php.net - error_reporting() <br/>링크: php.net - error_get_last() 🎜🎜a: int error_reporting ([ int $level ] )🎜🎜모두가 익숙할 것이므로 자세한 내용은 다루지 않겠습니다. 🎜🎜b: array error_get_last ( void)🎜🎜발생한 마지막 오류 가져오기🎜🎜일반적으로 PHP 실행 중 치명적인 오류를 가져오는 데 사용됩니다(PHP 5). 🎜🎜두 함수는 문자 그대로 밀접하게 관련되어 있지 않지만 다음 코드와 출력을 관찰하세요. 🎜

<?php 
register_shutdown_function(&#39;shutdown_function&#39;);
unknown_function();function shutdown_function() {
  print_r(error_get_last());
}/* output:Array(
    [type] => 1
    [message] => Uncaught Error: Call to undefined function unknown_function() in /app/t.php:3Stack trace:#0 {main}
  thrown
    [file] => /app/t.php
    [line] => 3)
*/
로그인 후 복사
로그인 후 복사
🎜error_get_last()마지막에 발생한 오류를 얻었음을 보여주지만 실제로는 error_reporting()에서 오류를 무시하는지 여부는 설명하지 않습니다. 따라서 error_get_last()를 사용할 때 일반적으로 무시되는 오류에 주의해야 합니다. 예: E_DEPRECATED🎜

2. set_error_handler()set_Exception_handler() 바인딩된 handler 언제 시작되나요? 어떻게 관련되어 있나요? 🎜🎜link : php.net - set_error_handler()<br/>링크: php.net - set_Exception_handler()< /code>🎜🎜a, <code>혼합 set_error_handler( 호출 가능 $error_handler [, int $error_types = E_ALL | E_STRICT ] )🎜🎜사용자 정의 오류 처리 기능 설정<br/>🎜🎜일반적으로 PHP에서 스크립트 실행 중에 중단되지 않는 오류가 발생할 때 트리거됩니다.<br/> 이를 사용하여 오류 로그를 기록하거나 출력 및 기타 작업을 수행합니다. 🎜🎜🎜참고: 🎜🎜🎜FALSE: 표준 오류 처리는 stderr로 출력할지 여부를 결정합니다. display_errors = true/false)🎜🎜1. $error_types 매개변수는 대부분 error_reporting()로 설정되어 있지만 다음을 권장합니다. E_ALL로 설정하세요. 처리해야 할 오류와 핸들러에서 처리할 필요가 없는 오류를 판단하는 것이 확실히 더 유연합니다.🎜

2、以下级别的错误不能由用户定义的函数来处理: E_ERROR E_PARSEE_CORE_ERRORE_CORE_WARNING E_COMPILE_ERRORE_COMPILE_WARNING,和在 调用 set_error_handler() 函数所在文件中产生的大多数 E_STRICT

3、handler被触发后, 并不会中断PHP运行.

4、bool error_handler ( int $errno , string $errstr [, string $errfile [, int $errline [, array $errcontext ]]] )<br/>注意error_handler的返回值:

b、callable set_exception_handler ( callable $exception_handler )

设置用户自定义的异常处理函数<br/>设置默认的异常处理程序,用于没有用 try/catch 块来捕获的异常。 在 exception_handler 调用后异常会中止。

注意:

注意点中2, 3项轻描淡写了一下PHP 5/PHP 7之间的不同却透露出重要的消息(坑..)<br/>PHP 7中, exception_handler 不再只接受Exception了, 并且接收了Error错误.<br/>link: php.net - PHP7 Errors列表

1、exception_handler 调用后异常会中止(脚本终止).

2、PHP 5, PHP 7的exception_handler并不相同.<br/>PHP 5: void handler ( Exception $ex )<br/>PHP 7: void handler ( Throwable $ex )

3、自 PHP 7 以来,大多数错误抛出 Error 异常,也能被捕获。 Error Exception 都实现了 Throwable 接口。

因此, set_error_handler() set_exception_handler() 之间的关系也迎刃而解:<br/>

PHP 5:

1、set_error_handler(): 负责非中断行错误.

2、set_exception_handler(): 负责没有被catch的异常(会中断).

3、Fatal Error等: 并不会被两者管理, 正常输出到屏幕上(弊端).

PHP 7:

1、set_error_handler(): 负责非中断行错误.

2、set_exception_handler(): 负责没有被catch的异常, Error(会中断)

3、Fatal Error等: 由set_exception_handler()管理.

3. register_shutdown_function()通常跟Exception/Error有关系么?

link: php.net - register_shutdown_function()

注册一个 callback ,它会在脚本执行完成或者 exit() 后被调用。

根据说明可以得出结论, 它与Exception/Error完全没关系.<br/>提出这个问题, 主要是因为, 在PHP5中Fatal Error并没有明确的接收地点, 所以我们通常配合error_get_last()来接收Fatal Error

<?php 
register_shutdown_function(&#39;shutdown_function&#39;);
unknown_function();function shutdown_function() {
  print_r(error_get_last());
}/* output:Array(
    [type] => 1
    [message] => Uncaught Error: Call to undefined function unknown_function() in /app/t.php:3Stack trace:#0 {main}
  thrown
    [file] => /app/t.php
    [line] => 3)
*/
로그인 후 복사
로그인 후 복사

然而随着PHP 7的到来, Error已经可以被set_exception_handler()捕捉了, 再通过error_get_last()就多余了. shutdown中更多的是一些版本冗余的工作.<br/>

实例

前言中的需求: 调试模式下, 将所有错误提前输出, 再输出页面内容.<br/>以下是demo, 省去了环境判断(debug环境), 大家可以根据下面这段代码, 了解本文中所说的各种handler的触发和调用情况.

<?php/*
要求: 将所有异常打印在屏幕最上方
*//* Fatal Error 中断脚本 -> shutdown_handler *///设置错误级别define("END_ERRORS", &#39;--END ERRORS--&#39; . PHP_EOL . PHP_EOL);
ini_set(&#39;display_errors&#39;, true);
ini_set(&#39;error_reporting&#39;, E_ALL & ~E_DEPRECATED);

set_error_handler(&#39;usr_err_handler&#39;, error_reporting()); //注册错误处理函数set_exception_handler(&#39;usr_ex_handler&#39;); //注册异常处理函数register_shutdown_function(&#39;shutdown_handler&#39;);    //注册会在php中止时执行的函数$global_errors = [];    //用于记录所有错误$errnos = [             //错误级别
    0 => &#39;ERROR&#39;,//PHP7 ERROR的CODE
    1 => &#39;E_ERROR&#39;,//FATAL ERROR(PHP5), E_ERROR
    2 => &#39;E_WARNING&#39;,    4 => &#39;E_PARSE&#39;,    8 => &#39;E_NOTICE&#39;,    16 => &#39;E_CORE_ERROR&#39;,    32 => &#39;E_CORE_WARNING&#39;,    64 => &#39;E_COMPILE_ERROR&#39;,    128 => &#39;E_COMPILE_WARNING&#39;,    256 => &#39;E_USER_ERROR&#39;,    512 => &#39;E_USER_WARNING&#39;,    1024 => &#39;E_USER_NOTICE&#39;,    2048 => &#39;E_STRICT&#39;,    4096 => &#39;E_RECOVERABLE_ERROR&#39;,    8192 => &#39;E_DEPRECATED&#39;,    16384 => &#39;E_USER_DEPRECATED&#39;,    30719 => &#39;E_ALL&#39;,
];function reset_errors(){    global $global_errors;
    $global_errors = [];
}function get_errnostr($errno){    global $errnos;    return $errnos[$errno];
}function set_errnos($errno, $errstr){    global $global_errors;
    $global_errors[] = [        &#39;errno&#39; => $errno,        &#39;errnostr&#39; => get_errnostr($errno),        &#39;errstr&#39; => $errstr,
    ];
}function print_errors($prefix){    global $global_errors;    foreach ($global_errors as $err) {//由于handler中依然有可能有error 因此放最后
        printf("[%s]: %s, %d, %s\n",
            $prefix, $err[&#39;errnostr&#39;], $err[&#39;errno&#39;], $err[&#39;errstr&#39;]);
    }
}//用户异常处理函数 (进来就中断脚本) PHP5只有Exception进来   PHP7Error和Exception//PHP7中 void handler (Throwable $ex) 可捕获Error和Exception两种异常, 暂不管//http://php.net/manual/en/language.errors.php7.php PHP7 Error阅读//内部如果有Error则触发Error函数, 再回到错误行继续执行function usr_ex_handler($ex){
    $content = ob_get_clean();  //让Exception/Error提前展示

    print_errors(&#39;EX ERROR&#39;);
    reset_errors();

    $errnostr = get_errnostr($ex->getCode());
    $errno = $ex->getCode();
    $errstr = $ex->getMessage();    if ($ex instanceof Exception) {
        printf("[EXCEPTION]: %s, %d, %s\n", $errnostr, $errno, $errstr);
    } else {//针对PHP7  $ex instanceof Error
        printf("[EX FATAL ERROR]: %s, %d, %s\n", $errnostr, $errno, $errstr);
    }    //由于handler中依然有可能有error 因此放最后
    print_errors(&#39;EX ERROR&#39;);
    reset_errors();    echo END_ERRORS;    echo $content;    return;
}//用户错误处理函数//E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING不能被用户处理function usr_err_handler($errno, $errstr, $errfile, $errline, $errcontext){
    set_errnos($errno, $errstr);    return true;    //如果函数返回 FALSE,标准错误处理处理程序将会继续调用。}//用户PHP终止函数function shutdown_handler(){
    $content = ob_get_clean();  //让Exception/Error提前展示
    $err = error_get_last();//检查一下是否有遗漏掉的错误 php5 fatal error
    if ($err[&#39;type&#39;] & error_reporting()) {
        set_errnos($err[&#39;type&#39;], $err[&#39;message&#39;]);
    }
    print_errors(&#39;ST ERROR&#39;);
    reset_errors();    echo $content;
}

ob_start();echo &#39;Main function...&#39;, PHP_EOL;//搞事情//throw new Exception(&#39;这是一个异常&#39;);trigger_error(&#39;这是一个用户error&#39;);//E_USER_NOTICEif (version_compare(PHP_VERSION, &#39;7.0.0&#39;) >= 0) {
    mcrypt_encrypt();//E_WARNING, E_DEPRECATED} else {
    mysql();
}
unknown_function(); //fatal error$content = ob_get_clean();//优先输出错误print_errors(&#39;MA ERROR&#39;);if (!empty($global_errors)) {    echo END_ERRORS;
}
reset_errors();//输出正文内容echo $content;
로그인 후 복사

以上就是全部内容了,更多相关问题请访问PHP中文网:https://www.php.cn/

위 내용은 PHP의 예외 및 오류 처리기에 대한 세부 정보 및 예의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:开发者头条
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿