>  기사  >  백엔드 개발  >  php5와 php7의 예외 처리 메커니즘(thinkphp5 예외 처리 분석)

php5와 php7의 예외 처리 메커니즘(thinkphp5 예외 처리 분석)

藏色散人
藏色散人앞으로
2019-03-28 13:31:303837검색

이 글은 주로 php5와 php7의 예외 처리 메커니즘을 소개합니다(thinkphp5 예외 처리 분석). 도움이 필요한 친구들에게 도움이 되길 바랍니다!

1.php 예외 및 오류

다른 언어에서는 예외와 오류가 다르지만 PHP 자체 오류가 발생하면 예외를 실행하는 대신 오류가 발생합니다. 게다가 대부분의 경우 PHP는 오류를 발생시키고 프로그램 실행을 종료합니다. PHP5에서는 try catch로 오류를 처리할 방법이 없습니다.

php7은 오류를 잡을 수 있습니다.

1.1 php5 오류 예외

// 1.异常处理
try{
  throw new Exception("Error Processing Request", 1);
}catch ( Exception $e){
  echo $e->getCode().'076402276aae5dbec7f672f8f4e5cc81';
  echo $e->getMessage().'076402276aae5dbec7f672f8f4e5cc81';
  echo $e->getLine().'076402276aae5dbec7f672f8f4e5cc81';
  echo $e->getFile().'076402276aae5dbec7f672f8f4e5cc81';
}

返回:

1
Error Processing Request
158
E:\phpwebenv\PHPTutorial\WWW\test\index.php

// 2.结果php错误处理机制
function MyErrorHandler($error,$errstr,$errfile,$errline){
echo 'a4b561c25d9afb9ac8dc4d70affff419 Custom error:0d36329ec37a2cc24d42c7229b69747a'.$error.':'.$errstr.'076402276aae5dbec7f672f8f4e5cc81';
echo "Error on line $errline in ".$errfile;
}
set_error_handler('MyErrorHandler',E_ALL|E_STRICT);
try{
// throw new Exception("Error Processing Request", 4);
  trigger_error('error_msg');
}catch ( Exception $e){
  echo $e->getCode().'076402276aae5dbec7f672f8f4e5cc81';
  echo $e->getMessage().'076402276aae5dbec7f672f8f4e5cc81';
  echo $e->getLine().'076402276aae5dbec7f672f8f4e5cc81';
  echo $e->getFile().'076402276aae5dbec7f672f8f4e5cc81';
}

结果:
Custom error:1024:error_msg
Error on line 164 in E:\phpwebenv\PHPTutorial\WWW\test\index.php

//3. 处理致命错误:脚本结束后执行
function shutdown_function(){
  $e = error_get_last();
  echo '0141e64b460264de306a9735a1994788';
  var_dump($e);
}
register_shutdown_function('shutdown_function');
try{
// throw new Exception("Error Processing Request", 4);
// trigger_error('error_msg');
  fun();
}catch ( Exception $e){
  echo $e->getCode().'076402276aae5dbec7f672f8f4e5cc81';
  echo $e->getMessage().'076402276aae5dbec7f672f8f4e5cc81';
  echo $e->getLine().'076402276aae5dbec7f672f8f4e5cc81';
  echo $e->getFile().'076402276aae5dbec7f672f8f4e5cc81';
}

结果:

Fatal error: Uncaught Error: Call to undefined function fun() in E:\phpwebenv\PHPTutorial\WWW\
test\index.php:172 Stack trace: #0 {main} thrown in E:\phpwebenv\PHPTutorial\WWW\test\index.php on line 172
array(4) {
  ["type"]=>
  int(1)
  ["message"]=>
  string(131) "Uncaught Error: Call to undefined function fun() in E:\phpwebenv\PHPTutorial\WWW\test\index.php:172
Stack trace:
#0 {main}
  thrown"
  ["file"]=>
  string(43) "E:\phpwebenv\PHPTutorial\WWW\test\index.php"
  ["line"]=>
  int(172)
}
以上方法可以看出,php没有捕获到异常,只能依赖set_error_handler()和register_shutdown_function();来处理,set_error_handler只能接受
异常和非致命的错误。register_shutdown_function():主要针对die()或致命错误,即程序终结后执行;所以php5没有很好的异常处理机制。

1.2 php7 예외 처리

// 处理致命错误:脚本结束后执行
function shutdown_function(){
    $e = error_get_last();
    echo 'e03b848252eb9375d56be284e690e873';
    var_dump($e);
}
register_shutdown_function('shutdown_function');
// 结果php错误处理机制
function MyErrorHandler($error,$errstr,$errfile,$errline){
    echo 'a4b561c25d9afb9ac8dc4d70affff419 Custom error:0d36329ec37a2cc24d42c7229b69747a'.$error.':'.$errstr.'076402276aae5dbec7f672f8f4e5cc81';
    echo "Error on line $errline in ".$errfile;
}
set_error_handler('MyErrorHandler',E_ALL|E_STRICT);
try{
    // throw new Exception("Error Processing Request", 4);
    // trigger_error('error_msg');
    fun();
}catch ( Error $e){
    echo $e->getCode().'076402276aae5dbec7f672f8f4e5cc81';
    echo $e->getMessage().'076402276aae5dbec7f672f8f4e5cc81';
    echo $e->getLine().'076402276aae5dbec7f672f8f4e5cc81';
    echo $e->getFile().'076402276aae5dbec7f672f8f4e5cc81';
}
结果:
0
Call to undefined function fun()
172
E:\phpwebenv\PHPTutorial\WWW\test\index.php
NULL  
register_shutdown_function();没有捕获到异常
// 2. 如果不用try catch 捕获

function exception_handler( Throwable $e){

    echo &#39;catch Error:&#39;.$e->getCode().&#39;:&#39;.$e->getMessage().&#39;<br/>&#39;;


}

set_exception_handler(&#39;exception_handler&#39;);

fun();

요약: Throwable은 Error 및 Exception의 기본 클래스입니다. 오류 캡처 필요

try{
    fun();
}catch ( Throwable $e){
    echo $e->getCode().'076402276aae5dbec7f672f8f4e5cc81';
    echo $e->getMessage().'076402276aae5dbec7f672f8f4e5cc81';
    echo $e->getLine().'076402276aae5dbec7f672f8f4e5cc81';
    echo $e->getFile().'076402276aae5dbec7f672f8f4e5cc81';
}

3. thinkphp5 프레임워크의 오류 처리:

 在异常错误处理类:Error有这个处理  
// 注册错误和异常处理机制
\think\Error::register();
 /**
     * 注册异常处理
     * @return void
     */
    public static function register()
    {
        error_reporting(E_ALL);
        set_error_handler([__CLASS__, 'appError']);
        set_exception_handler([__CLASS__, 'appException']);
        register_shutdown_function([__CLASS__, 'appShutdown']);
    }
当程序出现错误时,会执行这些异常、错误的函数;

데이터베이스에 연결한 후 예외 처리는 다음과 같습니다.

/**
     * 连接数据库方法
     * @access public
     * @param array         $config 连接参数
     * @param integer       $linkNum 连接序号
     * @param array|bool    $autoConnection 是否自动连接主数据库(用于分布式)
     * @return PDO
     * @throws Exception
     */
    public function connect(array $config = [], $linkNum = 0, $autoConnection = false)
    {
        if (!isset($this->links[$linkNum])) {
            if (!$config) {
                $config = $this->config;
            } else {
                $config = array_merge($this->config, $config);
            }
            // 连接参数
            if (isset($config[&#39;params&#39;]) && is_array($config[&#39;params&#39;])) {
                $params = $config[&#39;params&#39;] + $this->params;
            } else {
                $params = $this->params;
            }
            // 记录当前字段属性大小写设置
            $this->attrCase = $params[PDO::ATTR_CASE];

            // 数据返回类型
            if (isset($config[&#39;result_type&#39;])) {
                $this->fetchType = $config[&#39;result_type&#39;];
            }
            try {
                if (empty($config[&#39;dsn&#39;])) {
                    $config[&#39;dsn&#39;] = $this->parseDsn($config);
                }
                if ($config[&#39;debug&#39;]) {
                    $startTime = microtime(true);
                }
                $this->links[$linkNum] = new PDO($config[&#39;dsn&#39;], $config[&#39;username&#39;], $config[&#39;password&#39;], $params);
                if ($config[&#39;debug&#39;]) {
                    // 记录数据库连接信息
                    Log::record(&#39;[ DB ] CONNECT:[ UseTime:&#39; . number_format(microtime(true) - $startTime, 6) . &#39;s ] &#39; . $config[&#39;dsn&#39;], &#39;sql&#39;);
                }
            } catch (\PDOException $e) {
                if ($autoConnection) {
                    Log::record($e->getMessage(), &#39;error&#39;);
                    return $this->connect($autoConnection, $linkNum);
                } else {
                    throw $e;
                }
            }
        }
        return $this->links[$linkNum];
    }

当数据库链接失败后,可以重新链接或者直接抛出异常;

    /**
     * 析构方法
     * @access public
     */
    public function __destruct()
    {
        // 释放查询
        if ($this->PDOStatement) {
            $this->free();
        }
        // 关闭连接
        $this->close();
    }
当执行sql失败后,调用析构方法,关闭数据库链接;

4. PHP에서 오류가 발생하면 리소스가 해제됩니다.

php는 해석 스크립트이며, 각 PHP 페이지는 독립적인 실행 프로그램입니다. 어떤 방법을 사용하든 실행만 하면(die(),exit(), 치명적인 오류 종료 프로그램 포함) 결과가 반환됩니다. 서버로 이동하면 닫힙니다. 프로그램이 닫히고 리소스도 물론 해제됩니다.

unset(); 여러 변수 이름이나 개체 이름이 저장소 주소를 가리키는 경우 unset() 함수는 변수의 포인터만 삭제합니다. 이름 및 저장소 주소만 있고 unset은 지정된 저장소 주소의 내용을 파괴합니다.

Destructor 메서드: 인스턴스화된 개체에 이를 가리키는 다른 변수나 개체 이름이 없는 경우 이 메서드는 또는 스크립트가 종료된 후 개체 리소스가 해제될 때 이 메서드가 실행됩니다.

관련 권장 사항:

PHP7과 PHP5의 보안 차이(예)

PHP7의 추상 구문 tree (AST)가 변화를 가져온다

PHP7 언어의 실행 원리 (PHP7 소스 코드 분석)

PHP 7.4 2019년 12월 출시 예정

위 내용은 php5와 php7의 예외 처리 메커니즘(thinkphp5 예외 처리 분석)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 cnblogs.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제