我能夠嘗試/捕捉警告嗎?

我須要捕獲一些從PHP本機函數拋出的警告,而後處理它們。 php

特別: apache

array dns_get_record  ( string $hostname  [, int $type= DNS_ANY  [, array &$authns  [, array &$addtl  ]]] )

DNS查詢失敗時,它將引起警告。 函數

try / catch不起做用,由於警告也不例外。 spa

我如今有2個選擇: rest

  1. set_error_handler彷佛有些set_error_handler由於我必須使用它來過濾頁面中的每一個警告(這是真的嗎?); 日誌

  2. 調整錯誤報告/顯示,以使這些警告不會在屏幕上顯示,而後檢查返回值; 若是爲false ,則找不到主機名的記錄。 code

這裏的最佳作法是什麼? dns


#1樓

真正有效的解決方案是使用E_WARNING參數設置簡單的錯誤處理程序,以下所示: get

set_error_handler("warning_handler", E_WARNING);
dns_get_record(...)
restore_error_handler();

function warning_handler($errno, $errstr) { 
// do something
}

#2樓

您可能應該嘗試徹底消除警告,可是若是不可能,能夠在呼叫以前添加@(即@dns_get_record(...)),而後使用能夠獲取的任何信息來肯定警告是否發生或不。 string


#3樓

設置和還原錯誤處理程序

一種多是在調用以前設置您本身的錯誤處理程序,並稍後使用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()的返回值。 可是我建議不要這樣作,由於錯誤/警告會被觸發而不是被抑制。


#4樓

若是dns_get_record()失敗,它將返回FALSE ,所以您可使用@禁止顯示警告,而後檢查返回值。


#5樓

我想嘗試/捕獲警告,但同時保留一般的警告/錯誤日誌記錄(例如,在/var/log/apache2/error.log ); 處理程序必須爲此返回false 。 可是,因爲「 throw new ...」語句基本上會中斷執行,所以必須執行「 wrap in function」技巧,該技巧也在如下內容中進行了討論:

是否有靜態方法在php中引起異常

或者,簡而言之:

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 ...不過,我仍會保留此消息,由於我尚未這樣作沒有看到其餘地方記錄的這種行爲。

相關文章
相關標籤/搜索