首頁  >  文章  >  後端開發  >  php7的錯誤與異常處理

php7的錯誤與異常處理

齐天大圣
齐天大圣原創
2020-08-12 10:41:072161瀏覽

錯誤

錯誤是寫程式中不可避免的,如何去發現定位錯誤及改正更是一門學問。今天跟大家聊聊php7之後的錯誤與異常。

錯誤的分類

一般錯誤分為語法錯誤、執行階段錯誤、邏輯錯誤。語法以及運行時錯誤很容易去排查,但邏輯錯誤就不是那麼簡單的了。鄙人在判斷的時候也有多次將比較運算==寫成了賦值運算=,像我這種就很難去發現。一般隨著經驗的豐富(踩坑踩多了),會越來越容易找到邏輯錯誤。

控制錯誤的輸出

一般建議開發階段開啟錯誤輸出方便及時發現錯誤,上線階段為了安全性及美觀建議關閉錯誤輸出。

php提供了一個參數display_errors用來控制錯誤向瀏覽器、cli的輸出。有兩種方式可以來修改它,透過修改php.ini檔案或使用ini_set函數來設定。下面展示使用ini_set來設定屏蔽錯誤輸出的程式碼。

<?php
ini_set(&#39;display_errors&#39;, 0);

echo $a;
echo 0;
date();
echo 1;

該程式會正常輸出01,但不會輸出錯誤訊息。

錯誤報告等級

一般分為4大類

  • parse語法錯誤

  • error致命錯誤

  • warning警告等級錯誤

  • notice注意等級錯誤

在php.ini設定檔中,有選項error_reporting,該選項用來控制輸出何種等級的錯誤。常見的有E_ALL、E_WARNING、E_NOTICE。

可以透過函數error_reporting()來動態控制錯誤等級的輸出。

# 输出所有级别错误
error_reporting(E_ALL);
# 输出所有级别除了E_NOTICE
error_reporting(E_ALL & ~E_NOTICE);
# 输出所有级别除了E_NOTICE和E_WARNING
error_reporting(E_ALL & ~(E_NOTICE | E_WARNING));

display_errors與error_reporting的區別

display_errors是用來控制錯誤是否輸出,而error_reporting是用來控制輸出何種等級的錯誤。通常他們會搭配使用

ini_set(&#39;display_errors&#39;, 0); // 关闭错误输出
error_reporting(E_ALL);  // 输出所有级别的错误信息

上面的配置一般是上線階段,屏蔽所有的錯誤輸出,但是記錄錯誤到php的錯誤日誌裡。錯誤日誌的路徑是由選項error_log 決定的。

如果設定error_reporting為0值,則不輸出錯誤也不記錄錯誤日誌。

錯誤對於程式的影響

#當程式有語法錯誤時,程式是不會執行的。當有error層級的錯誤時,程式就會停止向下執行。 notice、及warning等級錯誤時不會影響程式的向下執行的。

error_reporting(E_ALL);  // 输出所有级别的错误信息

echo $a;
echo 0;
date();
echo 1;
new a;
echo 2;

程式會輸出0和1,但不會輸出2。

使用者自訂錯誤

trigger_error()函數可以生產一個使用者層級的錯誤。錯誤級別有E_USER_ERROR 、E_USER_WARNING、E_USER_NOTICE 等

<?php

trigger_error(&#39;这是notice级别错误&#39;, E_USER_NOTICE);
trigger_error(&#39;warning错误&#39;, E_USER_WARNING);
trigger_error(&#39;deprecated&#39;, E_USER_DEPRECATED);
trigger_error(&#39;error错误&#39;, E_USER_ERROR);

自定義錯誤處理

set_error_handler — 設置用戶自定義的錯誤處理函數,該函數原型如下:

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

該函數首個參數是一個回呼函數,原型如下:

handler ( int $errno , string $errstr [, string $errfile [, int $errline [, array $errcontext ]]] ) : bool
  • error 錯誤等級

  • errstr 錯誤訊息

  • #errfile 發送錯誤的檔案

  • errline 錯誤出現的行號

以下層級的錯誤不能由使用者定義的函數來處理:    E_ERROR、 E_PARSE、    E_CORE_ERROR、 E_CORE_WARNING、    E_COMPILE_ERROR、    E_COMPILE_WARNING,且大多數在set_error_handler() 位置所產生的函數所產生的函數。

<?php
 
define(&#39;DEBUG&#39;, false);
 
set_error_handler(&#39;error_handler&#39;);
 
if (DEBUG) {
    ini_set(&#39;display_errors&#39;, &#39;On&#39;);
} else {
    ini_set(&#39;display_errors&#39;, &#39;Off&#39;);
}
 
function error_handler($errLevel, $errInfo, $errFile, $errLine)
{
    echo "ErrorLevel:$errLevel: $errInfo In $errFile ON $errLine" . PHP_EOL;
}
 
echo $a;

異常

#

异常和错误时有区别的,错误一般是指我们能控制的问题,比如变量名写错了,或者判断条件写的不错,导致死循环。而异常通常指那些难以控制的、意料外的错误,比如mysql连接不上,文件句柄打开失败等情况。

php的异常也是经典的try catch finally,但和一般的异常处理不一样的是,绝大部分的异常需要自行抛出。抛出异常使用throw关键字完成。php也支持捕获多个异常。

<?php

class MyError extends Exception
{
    public function printErr ()
    {
        echo &#39;出错啦&#39;.PHP_EOL;
    }
}

class YourError extends Exception
{
    public function printErr ()
    {
        echo &#39;errors&#39;.PHP_EOL;
    }
}

try {
    if (mt_rand(0,1)) {
        throw new MyError(&#39;错误&#39;);
    } else {
        throw new YourError(&#39;错误&#39;);
    }


} catch (MyError $e) {
    $e->printErr();
} catch (YourError $e) {
    $e->printErr();
} finally {
    echo &#39;不管有没有异常,我都会被执行&#39;.PHP_EOL;
}

php的异常如果没有捕获,则会报Fatal Error错误,程序不会继续向下执行。

PHP 7 错误处理

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

异常处理

设置默认的异常处理程序,有try/catch捕获的话这个异常函数就不会执行,反之就会执行异常处理函数,而且执行的话,脚本将不会继续执行。

php使用set_exception_handler来设置用户自定义的异常处理函数   ,函数原型如下:

set_exception_handler ( callable $exception_handler ) : callable

回调函数的原型如下:

handler ( Throwable $ex ) : void

下面,我们来写一个异常处理函数

<?php

class MyError extends Exception
{
    public function printErr ()
    {
        echo &#39;出错啦&#39;.PHP_EOL;
    }
}

class YourError extends Exception
{
    public function printErr ()
    {
        echo &#39;errors&#39;.PHP_EOL;
    }
}

try {
    if (mt_rand(0,1)) {
        throw new MyError(&#39;错误&#39;);
    } else {
        throw new YourError(&#39;错误&#39;);
    }


} catch (MyError $e) {
    $e->printErr();
} catch (YourError $e) {
    $e->printErr();
} finally {
    echo &#39;不管有没有异常,我都会被执行&#39;.PHP_EOL;
}

统一处理错误与异常

学完了错误与异常,知道如何去使用自定义错误处理和异常处理,现在我们就可以统一处理错误与异常了。

<?php
 
class Errors
{
    // 处理非致命错误
    static function errorHandle($errLevel, $errInfo, $errFile, $errLine)
    {
        echo &#39;错误:&#39;.PHP_EOL;
        print_r([&#39;file&#39; => $errFile, &#39;level&#39; => $errLevel, &#39;line&#39; => $errLine, &#39;info&#39; => $errInfo]);
    }
 
    // 处理致命错误及异常
    static function exceptionHandle(Throwable $ex)
    {
        echo &#39;异常:&#39;.PHP_EOL;
        print_r([&#39;file&#39; => $ex->getFile(), &#39;level&#39; => $ex->getCode(), &#39;line&#39; => $ex->getLine(), &#39;info&#39; => $ex->getMessage()]);
    }
}
 
set_error_handler([&#39;Errors&#39;, &#39;errorHandle&#39;]);
set_exception_handler([&#39;Errors&#39;, &#39;exceptionHandle&#39;]);

以上是php7的錯誤與異常處理的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn