PHP錯誤、異常匯總
Error
Error等級
Fatal Error:致命錯誤(腳本終止執行)
E_ERROR 致命的錯誤執行時的致命錯誤,終止程式執行
EER_ERROR_SMPHERROR_SMPHERROR_FERROR_ERROR_ERRORD.
E_USER_ERROR使用者產生的致命錯誤
E_CORE_WARNING PHP初始化啟動過程中發生的警告 (非致命錯誤) 。
E_COMPILE_WARNING 編譯警告E_USER_WARNING 使用者產生的警告訊息
Notice Error:通知錯誤(僅給予通知訊息,但腳本不會終止執行。)
表示腳本遇到可能會表現為錯誤的情況.
set_error_handler()捕獲錯誤【有限制】
函數說明
set_error_handler($callback);//設定一個使用者的函數(error_handler)來處理腳本中出現的錯誤。
函數的限制
以下層級的錯誤不能由使用者定義的函數來處理: E_ERROR、 E_PARSE、 E_CORE_ERROR、 E_CORE_WARNING、 E_COMPILE_ERROR、 E_COMPI_LE_WARNING,並且在 18 號檔案中所產生的函數中所產生的數字中所產生。
也就是:set_error_handler($callback)只能捕獲系統產生的一些Warning、Notice等級的Error。
使用方法
<?phpset_error_handler("error_handler");function error_handler($errno,$errstr,$errfile,$errline){ $str=<<<EOF "errno":$errno "errstr":$errstr "errfile":$errfile "errline":$errlineEOF; //获取到错误可以自己处理,比如记Log、报警等等 echo $str; }echo $test;//$test未定义,会报一个notice级别的错误
輸出結果:
"errno":8"errstr":Undefined variable: test"errfile":/Users/shuchao/Desktop/handler.php"errline":13 如何捕获PHP的Fatal Error、Parse Error等
需求描述
取得PHP的fatal error,例如記錄到Log裡面,利於我們分析線上問題,可以做線上服務的監控。
兩個函數
register_shutdown_function()
register_shutdown_function($callback)
register_shutdown_function(),等到腳本你要註冊就進入腳本。 ,再把註冊進去的function拉出來執行.
register_shutdown_function()調用的3種情況:
腳本正常退出時;
在腳本運行(run-time not parse-time)出錯退出時;
在腳本運行(run-time not parse-time)出錯退出時;
用戶用戶呼叫exit方法退出時。
error_get_last()
error_get_last();//函數取得最後發生的錯誤。
此函數以陣列的形式傳回最後發生的錯誤。
回傳的陣列包含4 個鍵和值:
[type] - 錯誤類型
[message] - 錯誤訊息[file] - 發生錯誤所在的檔案
[line] - 發生錯誤所在的行
使用方法
<?php register_shutdown_function( "fatal_handler" ); define('E_FATAL', E_ERROR | E_USER_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_RECOVERABLE_ERROR| E_PARSE );function fatal_handler() { if( $error = error_get_last()) { $errno = $error["type"]; $errfile = $error["file"]; $errline = $error["line"]; $errstr = $error["message"]; $str=<<<EOF "errno":$errno "errstr":$errstr "errfile":$errfile "errline":$errlineEOF; //获取到错误可以自己处理,比如记Log、报警等等 echo $str; } }
強烈注意
在parse-time出錯的時候,是不會呼叫register_shutdown_function()函數的。只有在run-time出錯的時候,才會呼叫register_shutdown_function()。
下面我們舉例說明:
NO.1
error_handler.php
<?phpregister_shutdown_function("error_handler");function error_handler(){ echo "Yeah,it's worked!"; }function test(){}function test(){}
執行結果如下:
Fatal error: Cannot redeclare test() (
Fatal error: Cannot redeclare test() (🟎 ) in/Users/shuchao/Desktop/error_handler.php on line 7<?phpregister_shutdown_function("error_handler");function error_handler(){ echo "Yeah,it's worked!"; }if(true){ function test(){} }function test(){}
Fatal error: Cannot redeclare test() (previously declared in /Users/shuchao/Desktop/error_handler.php:9) in /Users/shuchao/Desktop/error_handler.php on line 7Yeah,it's worked!%
我们看到,上面回调了register_shutdown_function().
因为我们加了一个if()判断,if()里面的test()方法,相当于一个闭包,与外面的test()名称不冲突。
也就是,上面的代码在parse-time没有出错,而是在run-time的时候出错了,所以我们能够获取到fatal error。
NO.3
error_handler.php
<?phpregister_shutdown_function("error_handler");function error_handler(){ echo "Yeah,it's worked!";} test_error.php <?phpinclude './error_handler.php';function test(){}function test(){}
执行 test_error.php的结果如下
Fatal error: Cannot redeclare test() (previously declared in /Users/shuchao/Desktop/test_error.php:3) in/Users/shuchao/Desktop/test_error.php on line 4
原因分析
当我们在运行test_error.php的时候,因为redeclare了两个test()方法,所以php的语法解析器在parse-time的时候就出错了。 所以不能回调register_shutdown_function()中的方法,不能catch住这个fatal error。
NO.4
error_handler.php <?phpregister_shutdown_function("error_handler");function error_handler(){ echo "Yeah,it's worked!";} test_error.php <?phpfunction test(){}function test(){} include_all.php require './error_handler.php';require './test_error.php';
执行 include_all.php的结果如下
Fatal error: Cannot redeclare test() (previously declared in /Users/shuchao/Desktop/include_all.php:2) in /Users/shuchao/Desktop/include_all.php on line 3Yeah,it's worked!%
结果分析
上面我们捕获了fatal_error.因为在运行include_all.php的时候,include_all.php本身语法并没有出错,也就是在parse-time的时候并没有出错,而是include的文件出错了,也就是在run-time的时候出错了,这个时候是能回调register_shutdown_function()中的函数的。
强烈建议:如果我们要使用register_shutdown_function进行错误捕捉,使用NO.4,最后一种方法,可以确保错误都能捕捉到。
更优美的写法·获取所有错误
set_error_handler()与register_shutdown_function()、error_get_last()的结合使用 <?phpregister_shutdown_function( "fatal_handler" );set_error_handler("error_handler");define('E_FATAL', E_ERROR | E_USER_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_RECOVERABLE_ERROR| E_PARSE );//获取fatal errorfunction fatal_handler() { $error = error_get_last(); if($error && ($error["type"]===($error["type"] & E_FATAL))) { $errno = $error["type"]; $errfile = $error["file"]; $errline = $error["line"]; $errstr = $error["message"]; error_handler($errno,$errstr,$errfile,$errline); }}//获取所有的errorfunction error_handler($errno,$errstr,$errfile,$errline){ $str=<<<EOF "errno":$errno "errstr":$errstr "errfile":$errfile "errline":$errlineEOF;//获取到错误可以自己处理,比如记Log、报警等等 echo $str;} Exception Exception与Error的区别 Exception
当异常抛出的时候,我们是想要去捕获他,并去做处理的。所以异常经常被当做程序的控制流程使用。
Error
Error是不可恢复的,是在开发过程中要去解决的。
使用Exception的例子
我想执行insert语句插入一条数据,可能插入失败(比如ID重复),注意是可能失败,所以这是一个可能的情况,也就是异常情况。我们就可以使用异常来处理这个问题
try { $row->insert(); $inserted = true; } catch (Exception $e) { echo "There was an error inserting the row - ".$e->getMessage(); $inserted = false; }echo "Some more stuff";
如何catch一个未捕获的Exception
场景描述
假设程序中的有些地方直接throw了异常,没有进行catch。我们现在想要不管在程序的任何一个地方throw异常,即便在throw的地方没有被catch,我们也要能catch住,如何做到呢?
一个函数:set_exception_handler()
//设置默认的异常处理程序,用于没有用 try/catch 块来捕获的异常。 在 exception_handler 调用后异常会中止。
set_exception_handler()
使用示例
1、exception_handler.php <?phpset_exception_handler("my_exception");function my_exception($exception){ echo $exception->getMessage();} 2、test_exception.php <?phprequire "./exception_handler.php";throw new Exception("I am Exception");
现在我们运行 test_exception.php,结果如下:
I am Exception //证明我们throw的Exception被捕获了

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

PHP仍然具有活力,其在現代編程領域中依然佔據重要地位。 1)PHP的簡單易學和強大社區支持使其在Web開發中廣泛應用;2)其靈活性和穩定性使其在處理Web表單、數據庫操作和文件處理等方面表現出色;3)PHP不斷進化和優化,適用於初學者和經驗豐富的開發者。

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP和Python各有優劣,選擇取決於項目需求和個人偏好。 1.PHP適合快速開發和維護大型Web應用。 2.Python在數據科學和機器學習領域佔據主導地位。

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。
