问题:
使用PDO查找错误处理的最佳实践。我在网站,SO,书籍等上找到的选项
catch
区块中回显您的错误消息。 通过众多选项,您可以轻松地淹没到应该使用的选项中。当然,您可以使用MVC框架并让它为您处理错误日志记录,但如果您不使用MVC,它会是什么样子。
正如我所理解的那样,错误处理应该在开发环境:
中进行以下操作display_errors = On
display_startup_errors = On
error_reporting = -1
log_errors = On
或者,如果php.ini文件没有可用的访问权限:
error_reporting(-1);
ini_set("display_errors", 1);
在生产环境:
display_errors = Off
display_startup_errors = Off
error_reporting = E_ALL
log_errors = On
或者,如果php.ini文件没有可用的访问权限:
error_reporting(0);
以生产环境中的数据库连接为例。
代码:
<?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;
}
?>
问题:
答案 0 :(得分:2)
这是一个非常好的问题,但是一开始就有一个错误的前提:您正在为PDO提供错误报告,这些报告与站点范围的错误报告分开。这没什么意义:每种方式的PDO错误都与其他错误相同 - 文件系统错误,HTTP错误等等。因此,没有理由建立仅PDO错误报告。您所需要的只是正确设置站点范围的错误报告。
关于php.ini不可访问性还有一个错误的假设:您始终可以使用ini_set()函数设置任何配置指令。因此,将error_reporting设置为灾难性的0级是没有单一的原因。
要回答其余的问题,您只需要一点常识。
许多网站都说您应该在catch块中回显您的错误消息。 SO上的大量用户表示,由于安全风险,您不应该回复错误消息。
你认为自己是什么?向用户显示系统错误消息是否有用?向恶意用户显示系统内部是否有用?
其他人建议将其记录到文档根目录之外的日志文件中。
你对此有任何异议吗?
有些人使用错误处理将其记录到SQL表中。
难道你认为将数据库错误记录到数据库中是不是很矛盾?
在PHP中处理错误的最佳做法是什么?
您已经展示过:在开发中显示并登录prod。所有这些都通过几个简单的配置选项在站点范围内进行控制。
处理catch块中的错误的最佳做法是什么?
根本不使用try-catch块进行错误报告。您不会为应用中的每个查询编写带有友好错误消息的catch块强>,正如在另一个答案中建议的那样,是吗?
因此你的代码必须是
<?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);
现在回答你在评论中提出的问题。
自定义错误屏幕是一个非常不同的问题,您的代码特别糟糕。既不应该是404错误也不应该使用HTTP重定向(这对SEO来说非常糟糕)。
要创建自定义错误页面,您必须使用Web服务器功能(首选)或PHP脚本中的错误处理程序。
当遇到致命错误(并且未捕获的异常为1)时,PHP不响应200 OK HTTP状态但具有5xx状态。每个Web服务器都可以捕获此状态并显示相应的错误页面。例如。对于Apache,它将是
ErrorDocument 503 server_error.html
你可以写任何你想要的借口。
或者你可以在PHP中设置一个自定义错误处理程序来处理所有PHP错误,我在这篇文章中写的一个例子可以看到:The (im)proper use of try..catch.