> 백엔드 개발 > PHP7 > PHP7이 set_error_handler 및 set_Exception_handler를 사용하여 예외 메커니즘을 처리하는 방법

PHP7이 set_error_handler 및 set_Exception_handler를 사용하여 예외 메커니즘을 처리하는 방법

醉折花枝作酒筹
풀어 주다: 2023-02-17 22:52:02
앞으로
2387명이 탐색했습니다.

이 기사에서는 PHP7이 set_error_handler 및 set_Exception_handler를 사용하여 예외 메커니즘을 처리하는 방법을 소개합니다. 도움이 필요한 친구들이 모두 참고할 수 있기를 바랍니다.

PHP7이 set_error_handler 및 set_Exception_handler를 사용하여 예외 메커니즘을 처리하는 방법

PHP는 원래 프로세스 지향 언어로 설계되었기 때문에 예외 처리는 Java와 같은 try/catch 메커니즘을 사용하지 않습니다. 오류가 발생하면 페이지에 직접 표시되거나 로그에 기록됩니다. 웹 서버 오류 로그에서 PHP 오류는 E_ERROR, E_WARNING, E_PARSE, E_NOTICE 등과 같은 여러 수준으로 구분됩니다. E_ERROR 및 E_PARSE와 같은 심각한 오류의 경우 PHP는 스크립트 실행을 직접 종료합니다.

php5 버전의 경우 PHP의 표준 오류 처리 방법(페이지에 출력하거나 로그에 기록) 대신 set_error_handler를 사용하여 자체 오류 처리 방법을 등록할 수 있지만 일부 심각한 오류는 이러한 방식으로 처리할 수 없습니다. , 이 방법에 대한 매뉴얼의 소개를 살펴보겠습니다.

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

设置一个用户的函数(error_handler)来处理脚本中出现的错误。 

本函数可以用你自己定义的方式来处理运行中的错误, 例如,在应用程序中严重错误发生时,或者在特定条件下触发了一个错误(使用 trigger_error()),你需要对数据/文件做清理回收。 

重要的是要记住 error_types 里指定的错误类型都会绕过 PHP 标准错误处理程序, 除非回调函数返回了 FALSE。 error_reporting() 设置将不会起到作用而你的错误处理函数继续会被调用 —— 不过你仍然可以获取 error_reporting 的当前值,并做适当处理。 需要特别注意的是带 @ error-control operator 前缀的语句发生错误时,这个值会是 0。 

同时注意,在需要时你有责任使用 die()。 如果错误处理程序返回了,脚本将会继续执行发生错误的后一行。 

以下级别的错误不能由用户定义的函数来处理: E_ERROR、 E_PARSE、 E_CORE_ERROR、 E_CORE_WARNING、 E_COMPILE_ERROR、 E_COMPILE_WARNING,和在 调用 set_error_handler() 函数所在文件中产生的大多数 E_STRICT。
로그인 후 복사

매뉴얼에는 E_ERROR 및 E_PARSE와 같은 오류는 사용자가 처리할 수 없다고 매우 명확하게 나와 있습니다. 코드 데모를 살펴보겠습니다. (다음 예제는 php5.6으로 실행됩니다.)

<?php
 
//自定义的错误处理方法
function _error_handler($errno, $errstr ,$errfile, $errline)
{
    echo "错误编号errno: $errno<br>";
    echo "错误信息errstr: $errstr<br>";
    echo "出错文件errfile: $errfile<br>";
    echo "出错行号errline: $errline<br>";
}
 
set_error_handler(&#39;_error_handler&#39;, E_ALL | E_STRICT);  // 注册错误处理方法来处理所有错误
 
 
echo $foo[&#39;bar&#39;];  // 由于数组未定义,会产生一个notice级别的错误
로그인 후 복사

실행 결과:

错误编号errno: 8
错误信息errstr: Undefined variable: foo
出错文件errfile: D:\project\demo\demo.php
出错行号errline: 16
로그인 후 복사

이때, 에러 메시지는 평소처럼 페이지에 직접 출력되지 않고, 저희만의 방식으로 처리됩니다. set_error_handler 함수를 사용하지 않으면 이런 에러 메시지가 출력됩니다. 물론 오류가 페이지에 직접 표시되지 않도록 PHP의 오류 표시를 끌 수 있습니다.

Notice: Undefined variable: foo in D:\project\demo\demo.php on line 15
로그인 후 복사

이 처리 메커니즘은 꽤 좋아 보이지만 위에서 언급한 것처럼 모든 오류를 이 방법으로 처리할 수는 없습니다. 위 코드를 다음과 같이 수정하세요.

<?php

//自定义的错误处理方法
function _error_handler($errno, $errstr ,$errfile, $errline)
{
    echo "错误编号errno: $errno<br>";
    echo "错误信息errstr: $errstr<br>";
    echo "出错文件errfile: $errfile<br>";
    echo "出错行号errline: $errline<br>";
}

set_error_handler(&#39;_error_handler&#39;, E_ALL | E_STRICT);  // 注册错误处理方法来处理所有错误


echo $foo[&#39;bar&#39;];  // 由于数组未定义,会产生一个notice级别的错误

trigger_error(&#39;人为触发一个错误&#39;, E_USER_ERROR); //人为触发错误

foobar(3, 5);   //调用未定义的方法将会产生一个Error级别的错误
로그인 후 복사

다시 실행:

错误编号errno: 8
错误信息errstr: Undefined variable: foo
出错文件errfile: D:\project\demo\demo.php
出错行号errline: 15
错误编号errno: 256
错误信息errstr: 人为产生触发一个错误
出错文件errfile: D:\project\demo\demo.php
出错行号errline: 17

Fatal error: Call to undefined function foobar() in D:\project\demo\demo.php on line 19
로그인 후 복사

예상대로 처음 두 오류는 " catch"를 하여 당사에서 처리하였으나, 최종 Fatal Error는 당사가 등록한 오류 함수에 따라 처리되지 않고 기본 처리 방식을 사용하였습니다. 이 역시 PHP5 버전의 오류 처리에 있어서 큰 결점입니다. PHP7 이후 예외 처리 방법에 몇 가지 새로운 변경 사항이 있습니다. 매뉴얼의 소개를 살펴보겠습니다.

PHP 7 改变了大多数错误的报告方式。不同于传统(PHP 5)的错误报告机制,现在大多数错误被作为 Error 异常抛出。 

这种 Error 异常可以像 Exception 异常一样被第一个匹配的 try / catch 块所捕获。如果没有匹配的 catch 块,则调用异常处理函数(事先通过 set_exception_handler() 注册)进行处理。 如果尚未注册异常处理函数,则按照传统方式处理:被报告为一个致命错误(Fatal Error)。 

Error 类并非继承自 Exception 类,所以不能用 catch (Exception $e) { ... } 来捕获 Error。你可以用 catch (Error $e) { ... },或者通过注册异常处理函数( set_exception_handler())来捕获 Error。
로그인 후 복사

PHP7의 이 오류 처리 메커니즘은 대부분의 예외를 직접 처리할 수 있게 해주는 Java를 배우는 것과 같습니다. 아래 코드 예시 (다음 코드는 php7을 사용하여 실행)

<?php

//自定义的错误处理方法
function _error_handler($errno, $errstr ,$errfile, $errline)
{
    echo "错误编号errno: $errno<br>";
    echo "错误信息errstr: $errstr<br>";
    echo "出错文件errfile: $errfile<br>";
    echo "出错行号errline: $errline<br>";
}

set_error_handler(&#39;_error_handler&#39;, E_ALL | E_STRICT);  // 注册错误处理方法来处理所有错误


try
{
    echo $foo[&#39;bar&#39;];  // 由于数组未定义,会产生一个notice级别的错误

    trigger_error(&#39;人为产生触发一个错误&#39;, E_USER_ERROR); //人为触发错误

    foobar(3, 5);   //调用未定义的方法将会产生一个Error级别的错误
}
catch (Error $e)
{
    echo "Error code: " . $e->getCode() . &#39;<br>&#39;;
    echo "Error message: " . $e->getMessage() . &#39;<br>&#39;;
    echo "Error file: " . $e->getFile() . &#39;<br>&#39;;
    echo "Error fileline: " . $e->getLine() . &#39;<br>&#39;;
}
로그인 후 복사

실행 결과:

错误编号errno: 8
错误信息errstr: Undefined variable: foo
出错文件errfile: E:\project\demo\demo.php
出错行号errline: 17
错误编号errno: 256
错误信息errstr: 人为产生触发一个错误
出错文件errfile: E:\project\demo\demo.php
出错行号errline: 19
Error code: 0
Error message: Call to undefined function foobar()
Error file: E:\project\demo\demo.php
Error fileline: 21
로그인 후 복사

이런 방식으로 치명적인 오류를 포함하여 다양한 유형의 오류를 자체적으로 처리할 수 있습니다. try/catch를 사용하지 않으면 php7의 오류 메시지는 php5의 오류 메시지와 약간 다릅니다:

错误编号errno: 8
错误信息errstr: Undefined variable: foo
出错文件errfile: E:\project\demo\demo.php
出错行号errline: 17
错误编号errno: 256
错误信息errstr: 人为触发一个错误
出错文件errfile: E:\project\demo\demo.php
出错行号errline: 19

Fatal error: Uncaught Error: Call to undefined function foobar() in E:\project\demo\demo.php:21 Stack trace: #0 {main} thrown in E:\project\demo\demo.php on line 21
로그인 후 복사

치명적인 오류에 대한 설명은 다음과 같습니다: An Error Throw was not catch.

여기서 잡는 것은 Error 클래스의 오류만 잡는 것으로 제한되어 있으며 설명서에는 Error 클래스가 Exception 클래스의 하위 클래스가 아니라고 명시되어 있으므로 코드에서 Exception 오류를 잡으려면 동시에 불가능하지 않나요? 코드:

<?php

//自定义的错误处理方法
function _error_handler($errno, $errstr ,$errfile, $errline)
{
    echo "错误编号errno: $errno<br>";
    echo "错误信息errstr: $errstr<br>";
    echo "出错文件errfile: $errfile<br>";
    echo "出错行号errline: $errline<br>";
}

set_error_handler(&#39;_error_handler&#39;, E_ALL | E_STRICT);  // 注册错误处理方法来处理所有错误


try
{
    echo $foo[&#39;bar&#39;];  // 由于数组未定义,会产生一个notice级别的错误

    trigger_error(&#39;人为触发一个错误&#39;, E_USER_ERROR); //人为触发错误

    throw new Exception(&#39;This is a exception&#39;, 400);  //抛出一个Exception,看是否可以被catch

    foobar(3, 5);   //调用未定义的方法将会产生一个Error级别的错误
}
catch (Error $e)
{
    echo "Error code: " . $e->getCode() . &#39;<br>&#39;;
    echo "Error message: " . $e->getMessage() . &#39;<br>&#39;;
    echo "Error file: " . $e->getFile() . &#39;<br>&#39;;
    echo "Error fileline: " . $e->getLine() . &#39;<br>&#39;;
}
로그인 후 복사

실행 결과:

错误编号errno: 8
错误信息errstr: Undefined variable: foo
出错文件errfile: E:\project\demo\demo.php
出错行号errline: 17
错误编号errno: 256
错误信息errstr: 人为触发一个错误
出错文件errfile: E:\project\demo\demo.php
出错行号errline: 19

Fatal error: Uncaught Exception: This is a exception in E:\project\demo\demo.php:21 Stack trace: #0 {main} thrown in E:\project\demo\demo.php on line 21
로그인 후 복사

방법이 없을까요? 사실 매뉴얼


을 보면 Error 클래스와 Exception 클래스는 모두 Throwable의 하위 클래스이므로(실제로 Error 클래스와 Exception 클래스는 둘 다 Throwable 인터페이스를 구현합니다), 위 코드는 다음과 같이 최적화될 수 있습니다:

<?php

//自定义的错误处理方法
function _error_handler($errno, $errstr ,$errfile, $errline)
{
    echo "错误编号errno: $errno<br>";
    echo "错误信息errstr: $errstr<br>";
    echo "出错文件errfile: $errfile<br>";
    echo "出错行号errline: $errline<br>";
}

set_error_handler(&#39;_error_handler&#39;, E_ALL | E_STRICT);  // 注册错误处理方法来处理所有错误


try
{
    echo $foo[&#39;bar&#39;];  // 由于数组未定义,会产生一个notice级别的错误

    trigger_error(&#39;人为触发一个错误&#39;, E_USER_ERROR); //人为触发错误

    if (mt_rand(1, 10) > 5)
    {
        throw new Exception(&#39;This is a exception&#39;, 400);  //抛出一个Exception,看是否可以被catch
    }
    else
    {
        foobar(3, 5);   //调用未定义的方法将会产生一个Error级别的错误
    }
}
catch (Throwable $e)
{
    echo "Error code: " . $e->getCode() . &#39;<br>&#39;;
    echo "Error message: " . $e->getMessage() . &#39;<br>&#39;;
    echo "Error file: " . $e->getFile() . &#39;<br>&#39;;
    echo "Error fileline: " . $e->getLine() . &#39;<br>&#39;;
}
로그인 후 복사

여러 번 실행하면 예외 예외 또는 오류 예외인 경우 이를 포착하여 처리할 수 있습니다.

try/catch로 모든 오류를 처리하지 않으려면 set_Exception_handler를 사용하여 예외 처리 함수를 등록할 수도 있습니다. 그러면 포착되지 않은 예외가 발생할 때 시스템이 자동으로 등록된 처리기 함수를 호출하여 다음을 수행합니다. 핸들.

<?php

//自定义的错误处理方法
function _error_handler($errno, $errstr ,$errfile, $errline)
{
    echo "错误编号errno: $errno<br>";
    echo "错误信息errstr: $errstr<br>";
    echo "出错文件errfile: $errfile<br>";
    echo "出错行号errline: $errline<br>";
}

set_error_handler(&#39;_error_handler&#39;, E_ALL | E_STRICT);  // 注册错误处理方法来处理所有错误

function _exception_handler(Throwable $e)
{
    if ($e instanceof Error)
    {
        echo "catch Error: " . $e->getCode() . &#39;   &#39; . $e->getMessage() . &#39;<br>&#39;;
    }
    else
    {
        echo "catch Exception: " . $e->getCode() . &#39;   &#39; . $e->getMessage() . &#39;<br>&#39;;
    }
}

set_exception_handler(&#39;_exception_handler&#39;);    // 注册异常处理方法来捕获异常


echo $foo[&#39;bar&#39;];  // 由于数组未定义,会产生一个notice级别的错误

trigger_error(&#39;人为触发一个错误&#39;, E_USER_ERROR); //人为触发错误

if (mt_rand(1, 10) > 5)
{
    throw new Exception(&#39;This is a exception&#39;, 400);  //抛出一个Exception,看是否可以被catch
}
else
{
    foobar(3, 5);   //调用未定义的方法将会产生一个Error级别的错误
}
로그인 후 복사
错误编号errno: 8
错误信息errstr: Undefined variable: foo
出错文件errfile: E:\project\demo\demo.php
出错行号errline: 29
错误编号errno: 256
错误信息errstr: 人为触发一个错误
出错文件errfile: E:\project\demo\demo.php
出错行号errline: 31
catch Error: 0 Call to undefined function foobar()


错误编号errno: 8
错误信息errstr: Undefined variable: foo
出错文件errfile: E:\project\demo\demo.php
出错行号errline: 29
错误编号errno: 256
错误信息errstr: 人为触发一个错误
出错文件errfile: E:\project\demo\demo.php
出错行号errline: 31
catch Exception: 400 This is a exception
로그인 후 복사

이제 우리는 PHP7에서 다시 혼란스러울 수 있습니다. 어떤 것이 set_error_handler로 처리되고 어떤 것이 set_Exception_handler로 처리되는지 요약하면 일반적으로 스크립트에서 발생하지 않는 오류입니다. 종료는 set_error_handler 처리가 되며 스크립트 실행을 종료하는 심각한 오류는 오류로 발생하지만 절대적으로 발생하지는 않습니다. 위에서 인위적으로 트리거된

E_USER_ERROR는 스크립트 실행을 중단하는 오류이지만 그렇지 않습니다. 대신에 set_error_handler에 등록된 메소드에 의해 처리됩니다. 이는 이러한 유형의 오류가 우리 자신에 의해 인위적으로 생성되었기 때문일 수 있으므로 PHP7의 오류 처리는 여전히 다소 모호하므로 다음과 같은 경우에는 더 주의해야 합니다. 스스로 처리합니다.

추천 학습: php 비디오 튜토리얼

위 내용은 PHP7이 set_error_handler 및 set_Exception_handler를 사용하여 예외 메커니즘을 처리하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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