在连接类中使用 PDO 时如何显示 mysql 错误?

Posted

技术标签:

【中文标题】在连接类中使用 PDO 时如何显示 mysql 错误?【英文标题】:How to display mysql error while using PDO in a connection class? 【发布时间】:2013-03-15 08:45:43 【问题描述】:

我正在尝试编写一个小类,以便可以使用它连接到我的数据库但是我遇到了一个问题,即 PDO 没有显示错误。

我要做的是在查询失败时显示 mysql 错误,以便我知道错误是什么并修复它。

在我的通话中,我有 4 种方法需要捕获 mysql 错误。

startConnection()
getOneResult()
processQuery()
getDataSet()

这是我目前的课程 有人可以告诉我如何显示mysql错误。请注意,我尝试使用 try catch 来捕获错误,但这对我不起作用。

感谢您的帮助

<?php

class connection 

    private $connString;
    private $userName;
    private $passCode;
    private $server;
    private $pdo;
    private $errorMessage;

    private $pdo_opt = array (
                            PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
                            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
                            );



    function __construct($dbName, $serverName = 'localhost')

        //sets credentials
        $this->setConnectionCredentials($dbName, $serverName);

        //start the connect
        $this->startConnection();

    

    function startConnection()


            $this->pdo = new PDO($this->connString, $this->userName, $this->passCode, $this->pdo_opt);

            if( ! $this->pdo)

                $this->errorMessage  = 'Failed to connect to database. Please try to refresh this page in 1 minute. ';
                $this->errorMessage .= 'However, if you continue to see this message please contact your system administrator.';
                echo $this->getError();

            

    


    //this will close the PDO connection
    public function endConnection()

        $this->pdo->close;
    

    //return a dataset with the results
    public function getDataSet($query, $data = NULL)
    
        $cmd = $this->pdo->prepare( $query );

        $cmd->execute($data);
        return $cmd->fetchAll();
    


    //return a dataset with the results
    public function processQuery($query, $data = NULL)
    
        $cmd = $this->pdo->prepare( $query );

        return $cmd->execute($data);
    


    public function getOneResult($query, $data = NULL)
        $cmd = $this->pdo->prepare( $query );
        $cmd->execute($data);
        return $cmd->fetchColumn();
    

    public function getError()
        if($this->errorMessage != '')
            return $this->errorMessage;
        else
            return true;  //no errors found

    

    //this where you need to set new server credentials with a new case statment
    function setConnectionCredentials($dbName, $serv)

        switch($serv)

            case 'NAME':
                $this->connString   = 'mysql:host='.$serv.';dbname='.$dbName.';charset=utf8';
                $this->userName     = 'user';
                $this->passCode     = 'password';
            break;

            default:
                $this->connString   = 'mysql:host=localhost;dbname=rdi_cms;charset=utf8';
                $this->userName     = 'user';
                $this->passCode     = 'pass!';
            break;

            

    






?>

【问题讨论】:

您能粘贴一下您如何使用 try/catch 以及您在其中捕获的异常类型吗?此外,放置 try/catch 块的位置也很重要? 你用什么代码来测试? 【参考方案1】:

我会摆脱或不使用方法getError()getOneResult()processQuery()getDataSet()。使用该类来管理您的 PDO 连接。然后将您的 PDO 语句包装在 try...catch 中。

try

    $conn = new connection( "mydatabase" );
    $db = $conn->getPdoInstance();
    $stmt = $db->prepare( "SELECT * FROM `something`" );
    $stmt->execute();

catch( PDOException $e )

   // Catch the error message and do whatever you need to do with it

【讨论】:

getOneResult() 方法可以将无用代码的数量减少四倍。请不要反对那些想让他们的代码不那么臃肿的人。 getOneResult() 甚至没有按照它所说的去做。 “getOneResult” 建议它获取一行,但它没有,它可能会返回多个结果但只返回一列。 *sigh* 你确定会吗?您对 PDO 有很好的经验吗? 好的,所以它只会获取第一个结果,但也没有空间指定它应该获取哪一列,更不用说如果结果查询不止一行,它只会返回第一行,但您可能需要的是另一行。有更好的方法可以做到这一点,而且似乎很多 PDO 功能都受到了限制。 好吧,当有更多字段或行时 - 只是不要使用此功能。使用您认为适合特定结果集的一个。当您只需要单个标量值时 - 为什么不使用函数来获取单个标量值? “有更好的方法”并不意味着“每个人都必须遵循一种方法”。但是,如果您可以展示其中一种更好的方法并证明它确实更好-毫无疑问,OP 将不胜感激。【参考方案2】:

您不必显示错误消息,而只提出它。显示 mysql 错误消息会使您的站点不那么安全并且看起来很卑鄙。

所以,你唯一关心的就是

使 PDO 出现 SQL 错误异常。 设置 PHP 以使错误消息显示在开发服务器上并登录到实时服务器

因此,请在脚本顶部尝试此代码

ini_set('display_errors',1);
error_reporting(E_ALL);

然后运行这些函数之一并出现故意的 mysql 错误。您的脚本应该停止并显示错误消息。

更新: 好吧,我试着运行你的代码,上面这两条神奇的代码行帮助了我:

Notice: Undefined variable: pdo_opt in D:\SERVER\htdocs\0.php on line 37

表示变量拼写错误(您必须改用 $this-&gt;pdo_opt) - 所以,这就是 PDO 没有引发异常的原因。

这是一个教训,为什么 error_reporting 应该始终 E_ALL

【讨论】:

再次感谢先生。我试图显示错误的原因是调试原因仅此而已。我将使用 ini_set 来查看我的错误。如果我没有其他问题,我会更新这个问题。 你在我的课堂上发现的错误是我没有看到错误的原因:) 所以我现在确实看到了错误。既然你引导我开始写这门课的正确方向,你能给我一些关于这门课的反馈吗?我该如何改进它?再次感谢您的反馈:) @Mike 我希望我也有人来审查我自己的课程 :) 但是人们很少倾向于审查其他人的代码。所以,我满足于自己的经验法则:“最好的评论者是日常生活中的使用”。只需尝试将您的课程用于一些现实生活中的应用程序,看看它是否适合。虽然我一眼就看到了一些笔记。 1. 您需要一组方法来封装原始 PDO 方法,如 rowCount()、insertId()、fetch() 用于大型数据集的循环等。 2.您的 setConnectionCredentials 似乎不可靠。为什么不让它接受具有所有可能凭据的数组?

以上是关于在连接类中使用 PDO 时如何显示 mysql 错误?的主要内容,如果未能解决你的问题,请参考以下文章

PDO 的错误处理

在docker上使用laravel时无法连接到mysql数据库(未找到,pdo,连接被拒绝)

带有 PDOStatement 的 PDO 重新连接“mysql 服务器消失”错误

php使用pdo连接mysql数据库如何设置发送的字符集?

PHP中PDO关闭连接的问题

尝试使用 PDO 连接到错误的数据库时 PHP 不显示错误