php - PDO 使事务内的操作失败,但 commit 返回 true。为什么?

标签 php mysql pdo exception

我有以下代码

public function actualizarLogin($idusuario, $usu_login=NULL, 
            $usu_passwd=NULL) {
        $result=false;
        try {
            $db=new PDO(MYSQL_CON, MYSQL_USER, MYSQL_PASSWD,
                    array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
            try {
                $db->beginTransaction();
                $sql="UPDATE usuario SET usu_login=?, usu_passwd=? 
                        WHERE idusuario=?";
                $pstmt=$db->prepare($sql);
                $pstmt->bindParam(1, $usu_login, PDO::PARAM_STR);
                if($usu_passwd==null) {
                    $pstmt->bindParam(2, $usu_passwd, PDO::PARAM_NULL);
                } else {
                    $pstmt->bindParam(2, crypt($usu_passwd, CRYPT_MD5), PDO::PARAM_STR);
                }
                //Accidentaly using wrong variable here
                $pstmt->bindParam(3, $usu_login, PDO::PARAM_INT);
                $pstmt->execute();
                //But commit return true and no Exception is thrown
                $result=$db->commit();              
            } catch (PDOException $e) {
                $result=$e->getMessage();
                $db->rollBack();
                throw new RPC_INTERNAL_ERROR();
            }
        }catch (PDOException $e) {  
            $result=$e->getMessage();
            throw new RPC_INTERNAL_ERROR();
        }
        return $result;

RPC_INTERNAL_ERROR zoservices 是一个异常(exception),zoservices 是我用于 JSON-RPC 服务器的库,并且此方法是从客户端调用的。 正如您可以阅读代码中的注释一样,我犯了一个错误,这是非常人性化的错误,我使用了错误的变量来绑定(bind)最后一个参数,并且我告诉将其绑定(bind)为整数,而实际上是字符串(它是登录名而不是 ID)。但由于某种原因,即使我告诉在失败时抛出异常,也没有这样的异常,但最糟糕的是提交返回 true...为什么?我花了宝贵的时间来发现这个错误,因为 PDO 没有告诉我任何有关该错误的信息。有什么办法可以处理这些错误吗?

最佳答案

当您执行此操作时,PDO 不会抛出异常,因为这些输入参数为 coerced对您透明地指定类型。就数据库而言,不会发生错误,因为它接收到列数据类型的有效值。

这种行为在整个 PHP 中很普遍,因为替代方案是此代码将无法工作:

$foo = "4"; // not techically an int
$pstmt->bindParam(3, $foo, PDO::PARAM_INT);
$pstmt->execute();

如果您想强制绑定(bind)参数的匹配类型,则必须手动检查(例如,使用 PDOStatement::bindParam 的包装器来执行 gettype($param)并将结果与​​指定类型进行比较)。

关于php - PDO 使事务内的操作失败,但 commit 返回 true。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23517260/

相关文章:

PHP 搭建多语言站点的最佳实践

php - 如何计算内连接上两个表之间重复值的总数

php - 如何在多维数组上使用 array_multisort()

php - 编辑 hasMany 关联中的项目 (CakePHP)

php - 在文章索引中计算文章评论、点击和喜欢的正确方法是什么?

mysql - 安装snort,遇到SQL root密码问题

php - Zend_Db 和无缓冲查询

php - 消息 : SQLSTATE[HY093]: Invalid parameter number: parameter was not defined

php - PDO 准备语句 : Replacing the value of a column

php - 这个 MySQL 查询是最好的主意吗?