摘要:一的幾個函數異常捕獲自定義處理函數注冊錯誤捕獲自定義處理函數注冊程序執行時異常終止錯誤捕獲處理函數注冊這三個函數在錯誤處理控制中給開發者提供了很大的自主空間,在日志系統中記錄日志信息有他們的功勞。下面要說的類庫是借鑒了日志系統的設計。
引言
接觸過php框架的朋友們可能都知道,日志在項目中的重要作用了,他可以幫助我們定位錯誤的位置,讓程序更友好(處理得當的話不會直接拋出一大堆只有程序猿才真正動的英文),調試的時候也會很方便,還可以記錄一些重要的操作等等,總之一個完整的項目要是沒了日志系統,就已經開發的路上布滿了荊棘、坑洼,肯定會磕磕絆絆的。
簡介
要掌握PHP日志系統,必須先對這幾點東西了解透徹。
一、php的幾個函數
set_exception_handler(callback $exception_handler); //異常捕獲自定義處理函數注冊 set_error_handler(callback $error_handler); //錯誤捕獲自定義處理函數注冊 register_shutdown_function(callback $callback); //程序執行時異常終止錯誤捕獲處理函數注冊
這三個函數在錯誤處理控制中給開發者提供了很大的自主空間,在日志系統中記錄日志信息有他們的功勞。
在程序中出現異常(exception)問題時,php內核會拋出異常錯誤,然后將錯誤信息打印給使用者,如果注冊了exception處理函數,php拋出的異常會轉給自定義的注冊的異常捕獲函數,這個函數里面包含了我們要做的處理,記錄錯誤信息(包括錯誤詳細內容、錯誤位置),該函數處理完異常后,異常就會終止。
當程序中出現error時,我們注冊的error處理函數會在函數中將錯誤信息轉化為一個錯誤異常對象傳遞給異常處理函數,也就是第一步的$exception_handler函數。
當成續重出現shutdown錯誤時,會執行我們注冊的異常終止處理函數,該函數通過error_get_last()獲取到最后的shutdown時的錯誤對象,接著和上一部一樣,生成一個error exception對象,將該對象傳遞給我們注冊的異常處理函數。
可以看到,其實不管是異常還是錯誤,都是將自己的信息轉化為異常處理函數認識的異常信息,然后交給異常處理函數處理,非異常信息就像化了妝的女人一樣,異常處理程序不認識這些非異常信息,只有將裝卸掉(非異常信息自己轉化為異常信息,準確的說應該是拋出),異常處理才認識。
php日志系統中的錯誤處理流程
那么現在問題來了,這幾個函數一般會配合一個異常處理類庫,加上一個錯誤日志記錄類庫來進行工作,異常處理類庫中包含要注冊的3個函數,日志記錄類庫在$exception_handler中調用,用來合理的記錄和放置日志文件的位置,上面說到的幾個函數一般是在程序框架入口處進行加載注冊的,就像下面這樣:
這里面用的是array(class,function)這種方式。
set_exception_handler(array("Myexception","exceptionHandler")); set_error_handler(array("Myexception","errorHandler")); register_shutdown_function(array("Myexception","shutdownHandler"));
二、日志記錄相關類庫
第一部分介紹到的東西只是對異常、錯誤、shutdown進行了捕獲,這只是第一步,接下來還要對捕獲到的信息進行合理的處理,比如說記錄這些日志信息到本地文件系統中(這個操作是在array(“Myexception”,”exceptionHandler”)),這個地方就用到了日志記錄類庫。(下面要說的類庫是借鑒了kohana日志系統的設計)。
日式日志記錄也很簡單只要做的將信息添加到文件末尾就行,這個很容易實現,相信大家都可以自己實現,但是要設計出一個便捷的、高效的、擴展的日志記錄類庫就不那么簡單了,要經過長時間的實踐總結優化才可以,kohana框架中的日志記錄類庫已經比較成熟了,因此這里拿來借鑒。 相信使用過kohana的用戶一定對kohana框架中的日志記錄比較熟悉,不熟悉也沒關系,我下面會大概的說說,在kohana源碼中的application/bootstrap.php文件中的第109——112行可以看到下面的代碼: /** * Attach the file write to logging. Multiple writers are supported. */ Kohana::$log->attach(new Log_File(APPPATH."logs")); 這個就是添加一個日志記錄對象到日志對象中,注意橄欖色打底的倆個,他們是不同的類庫實例,在kohana中,日志記錄對象分為兩部分,第一部分就是日志對象,用來維護一個日志記錄對象的列表,這個要怎么理解呢,其實就像一個容器,里面包含了一個或多個日志記錄對象(這個就是第二部分,這些日志記錄對象才是真正來記錄日志的),還有每個對象要記錄的錯誤等級的數組,當滿足錯誤等級的時候才會去記錄,不滿足就會略掉。下面是我自己簡化重命名后的日志記錄方式: self::$log = Log::instance(); self::$log->attach(new Logwriter("./data/debug"),Log::DEBUG); self::$log->attach(new Logwriter("./data/notice"),Log::NOTICE); 我這里面為了更好地理解,將“容器”命名為Log,記錄的實例命名為Logwriter,可以看到我在程序入口處很容易的添加了兩不同的日志種類,第一個是記錄所有錯誤號比Log::DEBUG小的錯誤(錯誤級別比他高),并按規則記錄在文件夾./data/debug下面,第二個是記錄級別等于或高于Log::NOTICE的錯誤,當然了你還可以更詳細制定具體哪些錯誤好,傳遞數組就行了,這個就是我感覺方便、快捷的地方,我們可以根據需求來添加錯誤日志、分不同的日志目錄,下面看一幅圖也許會有助于理解:
log與logwriter的關系
通過上面的圖你就會看到Log是一個容器,包含了具體的不同的logwriter對象,每個對象可能要記錄不同的信息,當錯誤信息要刷到文件中的時候,會運行每一個Logwriter實例,看看自己是否要記錄errormessage中的錯誤,errormessage中的level不包含在Logwriter內時忽略。
這本分和第一部分怎么合作的呢?其實很簡單,當exception捕獲的異常時會調用添加一條錯誤信息(包括錯誤位置、錯誤代號、錯誤信息等信息)到Log容器中的errormessage數組中,然后當程序結束之后在將這些信息寫入文件,這里還要注意下,也許你在閱讀kohana代碼是發現沒有明顯的直接寫入到日志中去,這里面kohana優化的比較好,因為php的一次執行可能出現多個錯誤,如果來一個錯誤你就去記錄一次這樣會在程序返回之前占用多余的io和時間,所以kohana的做法是默認將所有的錯誤、異常、日志存放在Log::$errormessage中,并在實例化的時候講Log中的writer操作注冊register_shutdown_function,這個函數的作用是在程序異常終止或者執行完成之后執行,前面第一部分也有使用到,這樣日志記錄就不會對本次php的執行產生帶大的影響。
參考網站:
https://github.com/AizuYan/ph...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/22285.html
摘要:項目地址部署的方案都在腳本里頭,說明如下使用方法版本簡單介紹是一個利用轉發操作系統中部署的基于框架和框架以及一個的服務。個服務是部署在環境中,通過和進行發送和接收消息。在前臺以及整個主要利用去操作。 項目地址:https://github.com/yuyangit/BMProject 部署的方案都在腳本里頭,說明如下: BMPlatform使用方法 版本 v0.2 1.簡單介紹...
閱讀 1980·2021-09-26 10:19
閱讀 3249·2021-09-24 10:25
閱讀 1623·2019-12-27 11:39
閱讀 1919·2019-08-30 15:43
閱讀 663·2019-08-29 16:08
閱讀 3504·2019-08-29 16:07
閱讀 902·2019-08-26 11:30
閱讀 1270·2019-08-26 10:41