問題描述
問題:
尋找使用 PDO 進行錯誤處理的最佳實踐.我在網站、SO、書籍等上找到的選項
Finding best practice for error handling using PDO. The options I have found on websites, SO, books, etc.
- 很多網站都說您應該在
catch
塊中回顯錯誤消息. - SO 上的大量用戶表示,由于安全風險,您永遠不應回顯錯誤消息.
- 其他人建議將其記錄到文檔根目錄之外的日志文件中.
- 有些使用錯誤處理將其記錄到 SQL 表中.
有多種選項,很容易被淹沒在您應該使用的選項中.當然,您可以使用 MVC 框架并讓它為您處理錯誤日志,但是如果您不使用 MVC,它會是什么樣子.
With a multitude of options, it gets quite easy to drown into what option you should be using. Of course you could use a MVC framework and let it handle error logging for you, but how would it look like if you are not using MVC.
據我所知,開發環境中的錯誤處理應該如下所示:
As I have understood it error handling should like the following in development environment:
display_errors = On
display_startup_errors = On
error_reporting = -1
log_errors = On
或者如果無法訪問 php.ini 文件:
Or if no access is available to the php.ini file:
error_reporting(-1);
ini_set("display_errors", 1);
在生產環境:
display_errors = Off
display_startup_errors = Off
error_reporting = E_ALL
log_errors = On
或者如果無法訪問 php.ini 文件:
Or if no access is available to the php.ini file:
error_reporting(0);
以生產環境中的數據庫連接為例.
To take an example of a database connection in production environment.
代碼:
<?php
// Error handling
error_reporting(0);
// Get credentials from outside document root
require_once('../settings.php');
// Tests connection to database
try {
$dbh = new PDO(
sprintf(
'mysql:host=%s;dbname=%s;port=%s;charset=%s',
$settings['host'],
$settings['name'],
$settings['port'],
$settings['charset']
),
$settings['username'],
$settings['password']
);
// Prevents emulated prepares and activates error handling
// PDO::ERRMODE_EXCEPTION
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
// Catches errors raised by PDO
catch (PDOException $e) {
// Prints error messages to file
file_put_contents('/home/ubuntu/errors.log', 'Error: ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
// Shows generic error message to user
header('Location: 404.php');
exit;
}
?>
問題:
- 在 PHP 中一般處理錯誤的最佳做法是什么?
- 在 catch 塊中處理錯誤的最佳做法是什么?
推薦答案
這是一個很好的問題,但一開始就有一個錯誤的前提:您將 PDO 的錯誤報告與站點范圍的錯誤報告分開了.這毫無意義:PDO 錯誤在各個方面都與其他錯誤相同 - 文件系統錯誤、HTTP 錯誤等等.因此,沒有理由建立僅限 PDO 的錯誤報告.您只需要正確設置站點范圍的錯誤報告.
That's a very good question, but there is one wrong premise at the very beginning: you are taking error reporting for PDO separated from site-wide error reporting. Which makes very little sense: PDO errors in every way are the same as other errors - filesystem errors, HTTP errors, and so on. Thus, there is no reason in establishing PDO-only error reporting. All you need is to properly set site-wide error reporting.
還有一個關于 php.ini 不可訪問性的錯誤假設:您始終可以使用 ini_set() 函數設置任何配置指令.因此,將 error_reporting 設置為災難性級別 0 的原因不止于此.
There is also one wrong assumption regarding php.ini inaccessibility: you can always set any configuration directive using ini_set() function. Thus, here is not a single reason in setting error_reporting to disastrous level of 0.
要回答您的其余問題,您只需要一點常識即可.
To answer the rest of your questions all you need is a little common sense.
很多網站都說您應該在 catch 塊中回顯錯誤消息.SO 上的大量用戶表示,由于安全風險,您永遠不應該回顯錯誤消息.
A great number of websites say you should echo your error messages in your catch block. A large number of users on SO say that you should never echo error messages due to security risks.
你自己怎么看?向用戶顯示系統錯誤消息有什么好處嗎?向惡意用戶展示系統內部結構有什么好處嗎?
What you think yourself? Does it any good showing system error messages to user? Does it any good showing system internals to a malicious user?
其他人建議將其記錄到文檔根目錄之外的日志文件中.
Others are recommending logging it to a log file outside the document root.
您對此有異議嗎?
有些使用錯誤處理將其記錄到 SQL 表中.
Some use error handling to log it to a SQL table.
您不認為將數據庫錯誤記錄到數據庫中的想法很矛盾嗎?
Don't you think it's quite contradicting idea - to log database errors into database?
在 PHP 中一般處理錯誤的最佳做法是什么?
What is the best practice for handling errors in general in PHP?
您已經顯示了它:在開發中顯示并在生產中登錄.所有這些都通過幾個簡單的配置選項在站點范圍內進行控制.
You have shown it already: display in dev and log in prod. All is controlled site-wide through few simple configuration options.
在 catch 塊中處理錯誤的最佳做法是什么?
What is the best practice for handling errors in the catch-block?
根本不要使用 try-catch 塊來報告錯誤.您不會為應用中的每個查詢編寫帶有友好錯誤消息的 catch 塊strong>,正如另一個答案中所建議的那樣,是嗎?
NOT to use try-catch block for error reporting at all. You aren't going to write a catch block with a friendly error message for the every query in your app, as it's suggested in the other answer, are you?
因此你的代碼必須是
<?php
// Error handling
error_reporting(-1);
ini_set('display_errors',0);
ini_set('log_errors',1);
// Get credentials from outside document root
require_once('../settings.php');
// Tests connection to database
$dbh = new PDO(
sprintf(
'mysql:host=%s;dbname=%s;port=%s;charset=%s',
$settings['host'],
$settings['name'],
$settings['port'],
$settings['charset']
),
$settings['username'],
$settings['password']
);
// Prevents emulated prepares and activates error handling
// PDO::ERRMODE_EXCEPTION
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
現在回答您在評論中提出的問題.
Now to the question you voiced in the comment.
自定義錯誤屏幕是另一回事,您的代碼尤其糟糕.它既不應該是 404 錯誤,也不應該使用 HTTP 重定向(這對 SEO 來說非常糟糕).
A custom error screen is a very different matter and your code is especially bad with it. Neither it should be a 404 error nor an HTTP redirect have to be used (thats very bad for SEO).
要創建自定義錯誤頁面,您必須使用您的網絡服務器功能(首選)或 PHP 腳本中的錯誤處理程序.
To create a custom error page you have to use either your web-server features (preferred) or an error handler in PHP script.
當遇到致命錯誤(未捕獲異常就是其中之一)時,PHP 響應的不是 200 OK HTTP 狀態而是 5xx 狀態.每個網絡服務器都可以捕獲此狀態并顯示相應的錯誤頁面.例如.對于 Apache,它將是
When encountering a fatal error (and uncaught exception is one), PHP responds not with 200 OK HTTP status but with 5xx status. And every web-server can catch this status and show an according error page. E.g. for Apache it would be
ErrorDocument 503 server_error.html
你可以寫任何你想要的借口.
where you can write whatever excuses you want.
或者你可以在 PHP 中設置一個自定義的錯誤處理程序來處理所有的 PHP 錯誤,一個例子可以在我寫的關于這個問題的文章中看到:try..catch 的(im)正確使用.
Or you can set up a custom error handler in PHP which would handle all PHP errors as well, an example can be seen in the article I wrote on the matter: The (im)proper use of try..catch.
這篇關于使用 PDO 處理錯誤的最佳實踐的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!