这是一个非常好的问题,但是一开始就有一个错误的前提:您将 PDO 的错误报告与站点范围的错误报告分开。这毫无意义:PDO 错误在各个方面都与其他错误相同 - 文件系统错误、HTTP 错误等等。因此,没有理由建立仅 PDO 的错误报告。您所需要的只是正确设置站点范围的错误报告。
关于 php.ini 不可访问性还有一个错误的假设:您始终可以使用 ini_set() 函数设置任何配置指令。因此,这里并不是将 error_reporting 设置为灾难性级别 0 的唯一原因。
要回答您的其余问题,您所需要的只是一点常识。
许多网站表示您应该在 catch 块中回显错误消息。
SO 上的大量用户表示,由于安全风险,您永远不应该回显错误消息。
你自己怎么想?向用户显示系统错误消息有什么好处吗?向恶意用户展示系统内部结构有什么好处吗?
其他人建议将其记录到文档根目录之外的日志文件中。
您对此有异议吗?
有些使用错误处理将其记录到 SQL 表中。
您不认为将数据库错误记录到数据库中是非常矛盾的想法吗?
PHP 中一般处理错误的最佳实践是什么?
您已经展示过:在 dev 中显示并登录 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 脚本中的错误处理程序。
当遇到致命错误(未捕获的异常就是其中之一)时,PHP 不会以 200 OK HTTP 状态响应,而是以 5xx 状态响应。每个网络服务器都可以捕获此状态并显示相应的错误页面。例如。对于阿帕奇来说,这将是
ErrorDocument 503 server_error.html
在那里你可以写任何你想要的借口。
或者您可以在 PHP 中设置一个自定义错误处理程序,它也可以处理所有 PHP 错误,可以在我写的关于此事的文章中看到一个示例:(im) 正确使用 try..catch。 http://phpdelusions.net/delusion/try-catch#clarification