使用PDO的错误处理的最佳做法 [英] Best practice for error handling using PDO

查看:222
本文介绍了使用PDO的错误处理的最佳做法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:



找出使用PDO进行错误处理的最佳做法。


  1. 很多网站表示您应该在您的网站 catch 阻止。

  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);

生产环境

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

或者如果php.ini文件没有可用的访问权限:

  error_reporting(0); 

生产环境中举例说明数据库连接。 p>

代码:

 <?php 
//错误处理
error_reporting(0);

//从外部文档root获取凭据
require_once('../ settings.php');

//测试与数据库的连接
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']
);
//防止仿真准备并激活错误处理
// PDO :: ERRMODE_EXCEPTION
$ dbh-> setAttribute(PDO :: ATTR_EMULATE_PREPARES,false);
$ dbh-> setAttribute(PDO :: ATTR_ERRMODE,PDO :: ERRMODE_EXCEPTION);
}
//捕获PDO引发的错误
catch(PDOException $ e){
//打印错误消息到文件
file_put_contents('/ home / ubuntu / errors.log','Error:'。$ e-> getMessage()。PHP_EOL,FILE_APPEND);
//向用户显示一般错误消息
头('位置:404.php');
exit;
}
?>

问题:




  • PHP中处理错误的最佳做法是什么?

  • 在catch-block中处理错误的最佳做法是什么? li>

解决方案

这是一个很好的问题,但是最开始有一个错误的前提:将PDO的错误报告与站点范围的错误报告分开。这使得很少意义:PDO错误在各种方式都与其他错误相同 - 文件系统错误,HTTP错误等。因此,在建立仅PDO的错误报告中没有理由。所有你需要的是正确设置网站范围的错误报告。



还有一个错误的假设php.ini不可访问:你可以始终设置任何配置指令使用ini_set )函数。因此,这里没有一个原因将error_reporting设置为灾难性级别0。



要回答其余的问题,你需要的只是一点常识。 p>


许多网站表示您应该在您的catch块中回复您的错误消息。
SO上的大量用户表示,您不应该因为安全风险而回显错误消息。


自己?是否有任何好的显示系统错误消息给用户?


其他人建议将其记录到文档根目录以外的日志文件中。 p>

您对此有任何异议吗?


有些使用错误处理将其记录到SQL表。


不要认为这是一个矛盾的想法 - 记录数据库错误进入数据库?


在PHP中处理错误的最佳做法是什么?


您已经显示它:在dev中显示并登录prod。所有都是通过几个简单的配置选项在站点范围内控制。


在catch块中处理错误的最佳实践是什么? p>

不要使用try-catch块来进行错误报告。



因此,您的代码会显示在您的应用程式中的每个查询必须

 <?php 
//错误处理
error_reporting(-1);
ini_set('display_errors',0);
ini_set('log_errors',1);

//从外部文档root获取凭据
require_once('../ settings.php');

//测试与数据库的连接
$ 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']
);
//防止仿真准备并激活错误处理
// 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状态。每个Web服务器都可以捕获此状态并显示相应的错误页面。例如。对于Apache,它将是

  ErrorDocument 503 server_error.html 


您可以在PHP中设置一个自定义错误处理程序,处理所有PHP错误,一个例子可以在我写的文章中看到: The( im)正确使用try..catch。


Problem:

Finding best practice for error handling using PDO. The options I have found on websites, SO, books, etc.

  1. A great number of websites say you should echo your error messages in your catch block.
  2. A large number of users on SO say that you should never echo error messages due to security risks.
  3. Others are recommending logging it to a log file outside the document root.
  4. Some use error handling to log it to a SQL table.

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

Or if no access is available to the php.ini file:

error_reporting(-1);
ini_set("display_errors", 1);

And in production environment:

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

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.

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;
  }
?>

Question:

  • What is the best practice for handling errors in general in PHP?
  • What is the best practice for handling errors in the catch-block?

解决方案

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.

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.

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.

Do you have any objections for this?

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?

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.

What is the best practice for handling errors in the catch-block?

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?

Thus your code have to be

<?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.

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).

To create a custom error page you have to use either your web-server features (preferred) or an error handler in PHP script.

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.

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的错误处理的最佳做法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆