我熟悉一些基礎知識,但是我想知道更多關於什麼時候以及爲什麼應該在PHP中使用錯誤處理(包括拋出異常),特別是在活動網站或Web上應用程序。是否可以過度使用,如果是這樣,過度使用是什麼樣子?有沒有不應該使用它的情況?另外,在錯誤處理方面有哪些常見的安全問題?在PHP中處理錯誤
回答
有一件事要說,已經說了什麼是最重要的是,你在你的web應用程序中記錄任何錯誤到日誌中。這樣,正如傑夫「編碼恐怖」阿特伍德所建議的那樣,您會知道用戶何時遇到了應用程序問題(而不是「問他們出了什麼問題」)。
要做到這一點,我建議以下類型的基礎設施:
- 在數據庫中創建一個「崩潰」表和報告錯誤一組包裝類。我建議設置崩潰類別(「阻塞」,「安全」,「PHP錯誤/警告」(與例外)等)。
- 在所有錯誤處理代碼中,請確保記錄錯誤。一直這樣做取決於你如何建立API(上面的步驟) - 它應該是微不足道的記錄崩潰,如果做得對。
附加題:有時候,你的崩潰將是數據庫級的崩潰:即DB服務器關閉等,如果是這樣的話,你的錯誤日誌基礎設施(上圖)將失敗(您不能崩潰日誌以因爲日誌會嘗試寫入數據庫)。在這種情況下,我會寫故障轉移邏輯在你崩潰包裝類要麼
- 發送電子郵件給管理員和/或
- 記錄崩潰的細節,一個純文本文件
所有這些聽起來都像是過火,但相信我,這會影響您的應用程序是否被接受爲「穩定」或「片狀」。這種差異來自於所有應用程序始終如故/崩潰的事實,但那些瞭解應用程序所有問題的開發人員有機會實際修復它。
無影響的錯誤會停止腳本,這是一個很好的理由來處理它們。
一般來說,你可以使用try-catch塊來處理錯誤
try
{
// Code that may error
}
catch (Exception $e)
{
// Do other stuff if there's an error
}
如果你想停止出現在頁面上的錯誤或警告消息,那麼你可以像這樣一個@符號前綴通話。
@mysql_query($query);
使用查詢但它通常是一個好主意,做這樣的事情,所以你有什麼事情的一個更好的主意。
@mysql_query($query)
or die('Invalid query: ' . mysql_error() . '<br />Line: ' . __LINE__ . '<br />File: ' . __FILE__ . '<br /><br />');
不是輸出mysql_error,而是將其存儲在日誌中。這樣您就可以跟蹤錯誤(並且您不依賴用戶報告錯誤),並且可以進入並清除問題。
最好的錯誤處理是對用戶透明的那種,讓你的代碼理清問題,不需要涉及那個用戶傢伙。
如果您沒有顯式控制腳本正在處理的數據,則應該使用錯誤處理。我傾向於經常在例如表單驗證等地方使用它。知道如何在代碼中發現容易出錯的地方需要一些練習:一些常見的是在函數調用之後返回一個值,或者在處理來自數據庫查詢的結果時。你絕不應該假設函數的返回將會是你的期望,你應該確保按照預期編寫代碼。你不必使用try/catch塊,儘管它們很有用。很多時候你可以通過簡單的if/else檢查來獲得。
錯誤處理與安全編碼實踐密切相關,因爲存在大量「錯誤」,不會導致腳本簡單崩潰。儘管本身並不嚴格處理錯誤處理,但增加的字節有很多關於安全PHP編程基礎知識的4篇文章系列,您可以找到HERE。在這裏,還有很多其他的問題在關於如mysql_real_escape_string和Regular Expressions這些主題的stackoverflow,這可以非常強大的確認用戶輸入的數據的內容。
除了處理錯誤,在你的代碼的時候了,你還可以利用
http://us.php.net/manual/en/function.set-exception-handler.php
和
http://us.php.net/manual/en/function.set-error-handler.php
我發現,設置自己的異常處理程序特別有用。發生異常時,您可以根據異常類型執行不同的操作。
例如:當mysql_connet
調用返回FALSE
我拋出一個new DBConnectionException(mysql_error())
和處理這是一個「特殊」的方式:記錄錯誤,數據庫連接信息(主機,用戶名,密碼)等,甚至電子郵件的開發團隊,通知他們那些數據庫可能真的有問題
我使用它來補充標準錯誤處理。我不會推薦過度使用這種方法
最好的做法恕我直言是使用以下方法:1。 創建錯誤/異常處理程序 2,開始它在應用程序從內有
<?php
啓動 3.處理所有的錯誤
類調試{
public static setAsErrorHandler() {
set_error_handler(array(__CLASS__, '__error_handler'));
}
public static function __error_handler($errcode, $errmsg, $errfile, $errline) {
if (IN DEV) {
print on screen
}
else if (IN PRO) {
log and mail
}
}
}
調試:: setAsErrorHandler();
?>
粗略地說,錯誤是在PHP中的遺留問題,而例外的是對待錯誤的現代生活方式。最簡單的事情就是設置一個錯誤處理程序,它會拋出一個異常。這樣所有的錯誤都被轉換爲異常,然後你可以簡單地處理一個錯誤處理方案。以下代碼將爲您的錯誤轉換爲例外:
function exceptions_error_handler($severity, $message, $filename, $lineno) {
if (error_reporting() == 0) {
return;
}
if (error_reporting() & $severity) {
throw new ErrorException($message, 0, $severity, $filename, $lineno);
}
}
set_error_handler('exceptions_error_handler');
error_reporting(E_ALL^E_STRICT);
儘管有幾種情況,其中代碼是專門設計用於處理錯誤的。例如,在驗證文檔時,schemaValidate
method of DomDocument
會引發警告。如果您將錯誤轉換爲異常,它將在第一次失敗後停止驗證。有時這是你想要的,但是在驗證文檔時,你可能實際上想要全部失敗。在這種情況下,您可以臨時安裝收集錯誤的錯誤處理程序。這裏有一個小片段,我已經用於上述用途:
class errorhandler_LoggingCaller {
protected $errors = array();
function call($callback, $arguments = array()) {
set_error_handler(array($this, "onError"));
$orig_error_reporting = error_reporting(E_ALL);
try {
$result = call_user_func_array($callback, $arguments);
} catch (Exception $ex) {
restore_error_handler();
error_reporting($orig_error_reporting);
throw $ex;
}
restore_error_handler();
error_reporting($orig_error_reporting);
return $result;
}
function onError($severity, $message, $file = null, $line = null) {
$this->errors[] = $message;
}
function getErrors() {
return $this->errors;
}
function hasErrors() {
return count($this->errors) > 0;
}
}
和用例:
$doc = new DomDocument();
$doc->load($xml_filename);
$validation = new errorhandler_LoggingCaller();
$validation->call(
array($doc, 'schemaValidate'),
array($xsd_filename));
if ($validation->hasErrors()) {
var_dump($validation->getErrors());
}
用@屏蔽錯誤是非常緩慢的。
您還可以使用Google表單來捕獲和分析異常,而無需維護數據庫或公共可訪問的服務器。有一個教程here,解釋過程。
- 1. 在PHP中處理錯誤
- 2. 在PHP中處理錯誤
- 3. php中的錯誤處理
- 4. PHP處理錯誤
- 5. PHP錯誤處理
- 6. PHP - 錯誤處理
- 7. PHP錯誤處理
- 8. 在PHP中處理Web服務錯誤
- 9. 如何在PHP中處理fsockopen錯誤?
- 10. 在php中未處理的錯誤
- 11. 如何在PHP中處理SoapClient錯誤
- 12. 在PHP中處理數據庫錯誤
- 13. php symfony異常處理/錯誤處理
- 14. PHP錯誤處理和異常處理?
- 15. 錯誤處理PHP函數
- 16. MySQL和PHP錯誤處理
- 17. jquery parseJSON處理php錯誤
- 18. 錯誤處理PHP類
- 19. PHP MVC MySQL錯誤處理
- 20. datepicker php的錯誤處理
- 21. PHP的URL錯誤處理
- 22. PHP MySQL錯誤處理
- 23. SimpleXML的錯誤處理PHP
- 24. json_encode錯誤處理PHP OOP
- 25. PHP AJAX錯誤處理
- 26. PHP的錯誤處理
- 27. PHP simplexml_load_file - 錯誤處理
- 28. PHP類錯誤處理
- 29. PHP錯誤/異常處理 - 隱藏錯誤,但處理它?
- 30. 如何處理PHP中的db2_fetch_assoc錯誤?
雖然沒有使用mysql_error()函數存在安全風險? – VirtuosiMedia 2008-09-25 16:39:49
向用戶輸出mysql_error有潛在的風險。 – 2008-09-25 16:47:54
您可以在您的Web應用程序中設置一個標誌,以確定您處於測試環境還是生產環境中;在生產中,不要顯示錯誤,只需記錄它。在測試中,做兩個。 – 2008-09-25 19:19:29