【问题标题】:Error Checking for PDO Prepared Statements [duplicate]PDO 准备语句的错误检查 [重复]
【发布时间】:2013-02-22 22:00:22
【问题描述】:

我正在尝试使用 PDO 准备语句为 MySQL 数据库上的查询创建适当的错误处理。我希望程序在检测到准备好的语句过程中出现错误时退出。利用 PDO 准备语句过程中的每个步骤在失败时返回 False 的事实,我将这个令人反感的 hack 放在一起:

 global $allFields;
 global $db;
 global $app;
 //dynamically append all relevant fields to query using $allFields global
 $selectQuery = 'SELECT ' . implode($allFields, ', ') .
     ' FROM People WHERE ' . $fieldName . ' = :value';
 //prepared statement -- returns boolean false if failure running query; run success check
 $success = $selectQueryResult = $db->prepare($selectQuery);
     checkSuccess($success);
 $success = $selectQueryResult->bindParam(':value', $fieldValue, PDO::PARAM_STR);
     checkSuccess($success);
 $success = $selectQueryResult->execute();
     checkSuccess($success);

使用checkSuccess() 执行以下操作:

function checkSuccess($success) {
    if ($success == false) {
        //TODO: custom error page. 
        echo "Error connecting to database with this query.";
        die();
    }
}

两件事。首先,这是非常冗长和愚蠢的。一定会有更好的办法。显然,我可以将布尔值存储在数组或其他东西中以取出一行或两行代码,但仍然如此。

其次,是否有必要检查这些值,或者我应该在执行这行代码后检查结果:

$result = $selectQueryResult->fetch(PDO::FETCH_ASSOC);

我已经有这样的代码:

if ($result) { //test if query generated results
    // do successful shit
}

else {
    echo "404";
    $app->response()->status(404); //create 404 response header if no results

尽管我试图通过插入奇怪的、不匹配的或冗长的查询来破坏准备好的语句过程,但我的程序总是在我运行 @987654330 的任何函数上不返回 false 分配给 $result @。所以也许我根本不需要检查上述逻辑?请记住,我在程序的前面检查了成功的数据库连接。

【问题讨论】:

标签: php mysql


【解决方案1】:

你要赶上PDOException:

try {
    //your code/query
} catch (PDOException $e) {
    //Do your error handling here
    $message = $e->getMessage();
}

PDOException

【讨论】:

  • 并确保 PDO 抛出异常:$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  • 这对于部署到公众的代码是否安全?或者它是否有显示关于我的表格的敏感信息的风险?
  • @user1427661 您不应该在实时站点上显示技术错误消息。只需确保它们已被记录。
  • 那么我是否仍然可以启用错误报告,但只是让 try ... catch 块记录错误并显示自定义错误页面,其中包含有关数据库连接失败的模糊声明?
  • @YourCommonSense 这有点苛刻,catch 中的代码实际上并没有吐出任何内容://Do your error handling here 听起来对我来说是正确的。
【解决方案2】:

我更喜欢将错误模式设置为抛出这样的异常:

$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

在我连接到数据库之后。所以每个问题都会抛出 PDOException 所以你的代码是:

$selectQuery = '
                SELECT 
                    ' . implode($allFields, ', ') . ' 
                FROM 
                    People 
                WHERE 
                    ' . $fieldName . ' = :value
';
try
{ 
    $selectQueryResult = $db->prepare($selectQuery);
    selectQueryResult->bindParam(':value', $fieldValue);
    $selectQueryResult->execute();
}
catch(PDOException $e)
{
    handle_sql_errors($selectQuery, $e->getMessage());
}

函数在哪里:

function handle_sql_errors($query, $error_message)
{
    echo '<pre>';
    echo $query;
    echo '</pre>';
    echo $error_message;
    die;
}

事实上,我正在使用一个通用函数,它也有类似的东西

$debug = debug_backtrace();
echo 'Found in ' . $debug[0]['file'] . ' on line ' . $debug[0]['line'];

如果我运行多个查询,告诉我问题出在哪里

【讨论】:

  • 您还应该将prepare 语句放在try 块中。
  • @YourCommonSense 愿意分享更多信息吗?也..这只是一个与初始代码尝试类似的事情的示例..它也可以记录到文件,发送消息或任何类型的错误处理..问题是关于如何捕获错误,而不是如何处理它们
  • +1 到 @YourCommonSense 让我放心,如果我正在做一个快速而肮脏的实现,省略异常处理可能会在没有任何额外代码的情况下报告错误。
  • 我不同意 try / catch 块的不安全性。这一切都取决于你如何处理它们。将它们扔到显示器上,确定它们,将它们记录在某个地方……在 Web 根目录之外的文件中,在不可公开访问的数据库中……这些东西更安全。
  • @YourCommonSense 你的评论没有任何意义
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-24
  • 2013-10-26
  • 2014-01-12
  • 1970-01-01
  • 2015-10-28
相关资源
最近更新 更多