使用 PDO 处理错误的最佳实践

2023-12-26

Problem:

寻找使用 PDO 进行错误处理的最佳实践。我在网站、SO、书籍等上找到的选项。

  1. 许多网站表示您应该在您的catch block.
  2. SO 上的大量用户表示,由于安全风险,您永远不应该回显错误消息。
  3. 其他人建议将其记录到文档根目录之外的日志文件中。
  4. 有些使用错误处理将其记录到 SQL 表中。

由于有多种选项,您很容易陷入应该使用哪个选项的困境。当然,您可以使用 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);

And in 生产环境:

display_errors = Off
display_startup_errors = Off
error_reporting = E_ALL
log_errors = On

或者,如果无法访问 php.ini 文件:

error_reporting(0);

以数据库连接为例生产环境.

Code:

<?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 的错误报告。您所需要的只是正确设置站点范围的错误报告。

关于 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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 PDO 处理错误的最佳实践 的相关文章

  • Yii 使用 ajax 进行分页

    我需要使用ajax启用分页 我的代码 控制器 更新内容ajax function actionIndex dataProvider new CActiveDataProvider News array pagination gt array
  • 如何通过Elasticsearch模糊匹配电子邮件或电话?

    我想通过 Elasticsearch 对电子邮件或电话进行模糊匹配 例如 匹配所有以以下结尾的电子邮件 gmail com or 匹配所有电话开头136 我知道我可以使用通配符 query wildcard email gmail com
  • Woocommerce 让产品显示在存档页面中

    我正在尝试让所有产品显示在我商店的存档页面中 我想知道他们的id我正在使用我的一个钩子 它在 wp head 上运行并检查 if is product category 我想以某种方式访问 产品的查询并获取它们的 ID if is prod
  • Apache 访问 Linux 中的 NTFS 链接文件夹

    在 Debian jessie 中使用 Apache2 PHP 当我想在 Apache 的文档文件夹 var www 中创建一个新的小节时 我只需创建一个指向我的 php 文件所在的外部文件夹的链接 然后只需更改该文件夹的所有者和权限文件夹
  • MYSQL - 使用逗号分隔字符串作为变量输入的存储过程

    我希望有人能够提供帮助 我已经创建了我的第一个存储过程 没什么花哨的 但是我遇到了问题 我想给它一个字符串输入 例如 1 2 3 4 5 然后它执行一个简单的操作SELECT FROM TABLE WHERE EAN IN VAR 所以存储
  • 蛋糕控制台 2.2.1:烘焙错误

    运行 MAMP 的 OSX 机器 CakePHP 2 2 1 已正确安装和配置 这意味着当我浏览到 Index php 文件时 所有绿色条都显示出来 我已经完成了博客教程 并且正在开发我的第二个应用程序 其中脚手架已启动并运行 现在我第一次
  • 将“php”作为 shell 脚本执行时的自定义 php.ini 文件

    我在跑php作为 shell 脚本 我不确定 shell脚本 是否正确 该文件以 usr bin php 这很好用 但 MongoDB 类没有正确加载php ini文件 具有extension mongo so 未使用 我该如何使用它tha
  • 是否可以使用 PHP 重定向发送 POST 数据?

    更新 这不是重复的如何使用 PHP 发送 POST 请求 https stackoverflow com questions 5647461 how do i send a post request with php 那里的解决方案对我不起
  • SQL查询查找表的主键?

    我怎样才能找到哪一列首要的关键使用查询来创建表 这是重复的question https stackoverflow com questions 893874 mysql determine tables primary key dynami
  • MYSQL从每个类别中随机选择一条记录

    我有一个数据库Items表看起来像这样 id name category int 有几十万条记录 每个item可以是 7 种不同的之一categories 对应于categories table id category 我想要一个从每个类别
  • 学说迁移后备

    我们正在使用原则迁移 当迁移包含多个操作并且其中一个操作失败时 通常会出现问题 例如 如果迁移添加了 5 个外键 其中第 5 个失败 而字段长度不同 则修复字段错误并重新生成迁移不会not修复整个问题 而现在出现一个与 4 个密钥已存在有关
  • PHP 在输入流中使用 fwrite 和 fread

    我正在寻找将 PHP 输入流的内容写入磁盘的最有效方法 而不使用授予 PHP 脚本的大量内存 例如 如果可以上传的最大文件大小为 1 GB 但 PHP 只有 32 MB 内存 define MAX FILE LEN 1073741824 1
  • Mysql插入表后不显示右单引号(’)

    我有一个名为 测试 的表 我插入了一行 其中包含unicode字符右单引号 0x2019在名称字段中 SQL insert into Testing values Sno Name Address insert into Testing v
  • 表单提交后如何保留选择字段中的选定值?

    我有一个用于将票证上传到数据库的主页 我有一个选择字段 我想保留用户在提交表单之前选择的值 但它没有发生 这是我选择字段的代码
  • Doctrine EntityManager 清除嵌套实体中的方法

    我想用学说批量插入处理 http doctrine orm readthedocs org en latest reference batch processing html为了优化大量实体的插入 问题出在 Clear 方法上 它表示此方法
  • CURL 中的 data-urlencode 是什么意思?

    我搜索了很多个小时试图弄清楚 php curl 中的 data urlencode 是什么 我尝试过这个 但我认为这是不对的 xmlpost object1 file https www lob com goblue pdf 在文档中是 d
  • 如何在 PHP 中从 IP 地址/国家/地区名称查找时区 ID?

    谁能告诉我 PHP 中是否有任何方法可以从 IP 地址或国家 地区名称获取时区区域 例如 亚洲 加尔各答 描述 我正在尝试根据他 她的国家 地区设置用户时区 我从他的 IP 地址获取用户所在国家 地区 但我需要该国家 地区的时区区域 例如
  • 一次播种多行 laravel 5

    我目前正在尝试为我的用户表播种 如果我像这样尝试 2 行 就会失败 如果我只使用单个数组而不是 users 数组内的 2 个数组来创建一些假数据 那么效果很好 我做错了什么 正确的方法是什么 class UserTableSeeder ex
  • 简单的 PHP 表单:电子邮件附件(代码 Golf)

    想象一下 一个用户想要在其网站上放置一个表单 该表单将允许网站访问者上传一个文件和一条简单的消息 该消息将立即通过电子邮件发送 即 该文件未存储在服务器上 或者如果该文件存储在服务器上 仅暂时 作为文件附件 并在邮件正文中添加注释 查看更多
  • 对具有混合类型值的数组进行数字排序

    我有一个像这样的混合数组 fruits array lemon Lemon 20 banana apple 121 40 50 然后申请sort 其功能如下 sort fruits SORT NUMERIC foreach fruits a

随机推荐

  • Laravel 5. 使用 USING 运算符

    我尝试了很长时间才找到它 我不敢相信Laravel没有这个功能 所以 我可以写 select from a join b where a id b id 或者更漂亮 select from a join b using id 第一种情况对于
  • Pandas 与带有 WHERE 子句的 JOIN 类似

    我正在 python 的 pandas 中连接两个数据框 A 和 B 目标是接收来自 B 的所有纯行 sql 模拟 在 A client id B client id 上右连接 B 其中 A client id 为 null 在 panda
  • 如何使用 runhaskell 增加堆栈大小?

    我正在编写一些一次性 Haskell 脚本来解决一些问题欧拉计划 http projecteuler net问题 我真的不想编译它们 因为我经常需要进行大量的更改 但在某些情况下 我发现堆栈空间不足 的文档runhaskell表示以下语法应
  • MySQL 5.6 中的全局查询超时

    我需要在我的应用程序中在全局级别应用查询超时 查询 SET SESSION max execution time 1MySQL 5 7 就是这样做的 我使用的是MySQL 5 6 目前无法升级 任何使用 SQL Alchemy 的解决方案也
  • jSpinner时间选择器模型编辑

    我有 jSpinner 用于时间选择 问题一 用户可以编辑小时分钟和秒分隔符 并可以写入额外的数字 例如 123 问题2 模型始终获取当前时间 我想要 00 00 00 当我在代码中编写此内容而不是 hh mm ss 时 用户无法编辑这些值
  • Hibernate 4 -> 5 迁移:NamingStrategy 更改,找不到表

    我想做的事 我正在尝试从 WildFly 8 2 0 迁移到 WildFly 10 0 0 这意味着我已经 并且想要 从 Hibernate 4 3 迁移到 Hibernate 5 0 Setup Java 8u40 Spring 4 1
  • WPF ListView 关闭选择

    是否可以关闭WPF的选择ListView 那么当用户单击行时 该行不会突出显示 source konim5am at artax karlin mff cuni cz https artax karlin mff cuni cz 7Ekon
  • .NET:可执行文件应该进行强名称签名吗?私有 DLL 怎么样?

    我的应用程序由三个程序集组成 一个引用几个 DLL 的 EXE 这些 DLL 是我的应用程序私有的 它们仅由该可执行文件使用 应该给这些程序集起一个响亮的名字吗 FxCop 建议他们应该 对于目前生产的所有组件 CA2210 使用强名称密钥
  • Visual Studio 2015 OpenMP 支持

    我在 Visual Studio 2015 中获取 OpenMP 支持时遇到问题 我已经将项目选项配置为使用 openmp 项目 gt 属性 gt C C gt 语言 gt OpenMP支持 是 代码如下 非常简单的代码 用于测试OpenM
  • 仅打印字符串中的第一个字段

    我有一个约会12 12 2013 14 32我想将其转换为仅12 12 2013 该字符串可以是1 1 2013 12 32 or 1 10 2013 23 41我只需要日期部分 您可以使用各种 Unix 工具轻松完成此操作 cut d f
  • 将 ul 嵌套在 ol 中

    我试图创建一个有序列表 其中包含两个项目 每个列表下包含三个项目 其中有项目符号点 我的代码未通过验证 因为它表示在此上下文中不允许元素 ul 作为元素 ol 的子元素 但我到处都看到它说这没问题 这是我的代码 ol li First nu
  • 链接器输入文件未使用,因为链接未完成 - gcc

    我是编写 makefile 的初学者 我有一个类似这样的 makefile PATH1 ref CC gcc LINK gcc INCLUDES INCLUDES I PATH1 inc I PATH1 abc inc I PATH1 de
  • Modernizr 如何做边框半径

    你能帮我解释一下吗Modernizr 如果我使用某个功能 例如 border radius 我使用旧版浏览器运行它 现代化者是否会自动将 css 添加到页面 或者我应该编写代码来呈现控件以使其看起来像有边框一样 如果第二种情况属实 那么我为
  • 如何验证历史数据?

    目前 我们正在使用日历实例读取日期 以便使用 SparkSQL 选取最后一个月的记录 现在我们需要 如果在前一天添加额外的事件 我们还必须能够手动插入摘要开始和结束日期 以防我们需要手动重新运行之前时间段的作业 例如 手动重新运行表可能如下
  • HTML5 和 RDFa 支持

    我即将向现有的 HTML5 Web 应用程序引入开放图谱协议 并且我希望包含必要的 RDFa 数据 而不引入任何不必要的杂项 我看过HTML RDFa 1 1 http www w3 org TR rdfa in html 草稿并与Face
  • CSS 中内嵌的 SVG 图像

    这是一个基本的 SVG 图像悬停动画 有没有一种编码方法可以避免编写 SVG 代码两次 body background color 181818 a webkit transition all 3s ease moz transition
  • Pandas Concat 遇到内存错误

    我正在尝试预处理数据以进行进一步分析 首先 我从 csv 文件 x 中读取数据 然后我把它分成三个部分 最后我需要使用转换一个数组get dummies concat and sum的结果groupby import pandas as p
  • Android 中的静音流

    我构建了一个小应用程序 可以使用该类将音乐流静音 取消静音AudioManager 事实上 它一直有效 直到我关闭应用程序 即 我已将流静音 关闭应用程序 重新启动应用程序 并且按钮不再取消流静音 我在网上搜索过 但似乎没有人遇到过这个问题
  • 我应该使用哪种分层模型?邻接、嵌套还是枚举?

    我有一个表 其中包含世界上所有地理位置及其关系的位置 这是一个显示层次结构的示例 您将看到数据实际上存储为所有三个 枚举路径 邻接表 嵌套集 数据显然也永远不会改变 以下是英国布莱顿地点的直系祖先的示例 该地点的 woeid 为 13911
  • 使用 PDO 处理错误的最佳实践

    Problem 寻找使用 PDO 进行错误处理的最佳实践 我在网站 SO 书籍等上找到的选项 许多网站表示您应该在您的catch block SO 上的大量用户表示 由于安全风险 您永远不应该回显错误消息 其他人建议将其记录到文档根目录之外