我須要捕獲一些從PHP本機函數拋出的警告,而後處理它們。 php
特別: apache
array dns_get_record ( string $hostname [, int $type= DNS_ANY [, array &$authns [, array &$addtl ]]] )
DNS查詢失敗時,它將引起警告。 函數
try
/ catch
不起做用,由於警告也不例外。 spa
我如今有2個選擇: rest
set_error_handler
彷佛有些set_error_handler
由於我必須使用它來過濾頁面中的每一個警告(這是真的嗎?); 日誌
調整錯誤報告/顯示,以使這些警告不會在屏幕上顯示,而後檢查返回值; 若是爲false
,則找不到主機名的記錄。 code
這裏的最佳作法是什麼? dns
真正有效的解決方案是使用E_WARNING
參數設置簡單的錯誤處理程序,以下所示: get
set_error_handler("warning_handler", E_WARNING); dns_get_record(...) restore_error_handler(); function warning_handler($errno, $errstr) { // do something }
您可能應該嘗試徹底消除警告,可是若是不可能,能夠在呼叫以前添加@(即@dns_get_record(...)),而後使用能夠獲取的任何信息來肯定警告是否發生或不。 string
設置和還原錯誤處理程序
一種多是在調用以前設置您本身的錯誤處理程序,並稍後使用restore_error_handler()
恢復先前的錯誤處理程序。
set_error_handler(function() { /* ignore errors */ }); dns_get_record(); restore_error_handler();
您能夠基於這個想法並編寫可重複使用的錯誤處理程序,爲您記錄錯誤。
set_error_handler([$logger, 'onSilencedError']); dns_get_record(); restore_error_handler();
把錯誤變成異常
您可使用set_error_handler()
和ErrorException
類將全部php錯誤轉換爲異常。
set_error_handler(function($errno, $errstr, $errfile, $errline, $errcontext) { // error was suppressed with the @-operator if (0 === error_reporting()) { return false; } throw new ErrorException($errstr, 0, $errno, $errfile, $errline); }); try { dns_get_record(); } catch (ErrorException $e) { // ... }
使用本身的錯誤處理程序時要注意的重要一點是,它將繞過error_reporting
設置,並將全部錯誤(通知,警告等)傳遞給您的錯誤處理程序。 您能夠在set_error_handler()
上設置第二個參數,以定義要接收的錯誤類型,或使用錯誤處理程序中的... = error_reporting()
訪問當前設置。
禁止警告
另外一種可能性是使用@運算符禁止調用,而後再檢查dns_get_record()
的返回值。 可是我建議不要這樣作,由於錯誤/警告會被觸發而不是被抑制。
若是dns_get_record()
失敗,它將返回FALSE
,所以您可使用@
禁止顯示警告,而後檢查返回值。
我想嘗試/捕獲警告,但同時保留一般的警告/錯誤日誌記錄(例如,在/var/log/apache2/error.log
); 處理程序必須爲此返回false
。 可是,因爲「 throw new ...」語句基本上會中斷執行,所以必須執行「 wrap in function」技巧,該技巧也在如下內容中進行了討論:
或者,簡而言之:
function throwErrorException($errstr = null,$code = null, $errno = null, $errfile = null, $errline = null) { throw new ErrorException($errstr, 0, $errno, $errfile, $errline); } function warning_handler($errno, $errstr, $errfile, $errline, array $errcontext) { return false && throwErrorException($errstr, 0, $errno, $errfile, $errline); # error_log("AAA"); # will never run after throw /* Do execute PHP internal error handler */ # return false; # will never run after throw } ... set_error_handler('warning_handler', E_WARNING); ... try { mkdir($path, 0777, true); } catch (Exception $e) { echo $e->getMessage(); // ... }
編輯:仔細檢查後,發現它不起做用:「 return false && throwErrorException ...
」基本上將不會引起異常,而只是登陸錯誤日誌; 刪除「 false &&
」部分(如「 return throwErrorException ...
」中的部分),將使異常拋出工做正常進行,但隨後將不登陸error_log ...不過,我仍會保留此消息,由於我尚未這樣作沒有看到其餘地方記錄的這種行爲。