首頁 > 後端開發 > PHP7 > 主體

php5和php7的異常處理機制(thinkphp5 異常處理的分析)

藏色散人
發布: 2023-02-17 11:30:02
轉載
3632 人瀏覽過

這篇文章主要來介紹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().'<br/>';
  echo $e->getMessage().'<br/>';
  echo $e->getLine().'<br/>';
  echo $e->getFile().'<br/>';
}

返回:

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

// 2.结果php错误处理机制
function MyErrorHandler($error,$errstr,$errfile,$errline){
echo '<b> Custom error:</b>'.$error.':'.$errstr.'<br/>';
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().'<br/>';
  echo $e->getMessage().'<br/>';
  echo $e->getLine().'<br/>';
  echo $e->getFile().'<br/>';
}

结果:
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 '<pre/>';
  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().'<br/>';
  echo $e->getMessage().'<br/>';
  echo $e->getLine().'<br/>';
  echo $e->getFile().'<br/>';
}

结果:

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 '<pre class="brush:php;toolbar:false">';
    var_dump($e);
}
register_shutdown_function('shutdown_function');
// 结果php错误处理机制
function MyErrorHandler($error,$errstr,$errfile,$errline){
    echo '<b> Custom error:</b>'.$error.':'.$errstr.'<br/>';
    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().'<br/>';
    echo $e->getMessage().'<br/>';
    echo $e->getLine().'<br/>';
    echo $e->getFile().'<br/>';
}
结果:
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 的基類,在php7中,如果既想捕獲異常有需要捕獲錯誤

try{
    fun();
}catch ( Throwable $e){
    echo $e->getCode().&#39;<br/>&#39;;
    echo $e->getMessage().&#39;<br/>&#39;;
    echo $e->getLine().&#39;<br/>&#39;;
    echo $e->getFile().&#39;<br/>&#39;;
}
登入後複製

 3.thinkphp5框架的錯誤處理:#

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

 3.thinkphp5框架的錯誤處理:

/**
     * 连接数据库方法
     * @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失败后,调用析构方法,关闭数据库链接;
登入後複製
連結資料庫後,處理異常的是:rrreee

 4. php發生錯誤時,資源釋放

php是解釋性腳本,每個php頁面都是獨立的執行程序,不管用什麼方式只要執行完了(包括die(),exit(),致命錯誤終止程序),都會把結果傳回給伺服器,都會關閉。程式都關閉了,資源當然會被釋放;

unset();當多個變數名稱或物件名稱指向一塊儲存位址時,unset()函數的作用只是銷毀變數名稱和儲存位址的指向而已,當只有一個變數名或物件名,unset銷毀的是指定的儲存位址上的內容;

析構方法:當實例化的對象,沒有其他變數或物件名稱指向時,就會執行此方法;或是在腳本結束後,釋放物件資源時,執行此方法;

相關推薦:

PHP7和PHP5在安全性上的差異(實例)

PHP7 的抽象語法樹(AST)帶來的變化

PHP7語言的執行原理(PHP7源碼分析)

PHP 7.4預計在2019年12月發布###》######

以上是php5和php7的異常處理機制(thinkphp5 異常處理的分析)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:cnblogs.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!