我有以下代码
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/