我有以下代码
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的一个例外,zoservices是我用于JSON-RPC服务器的库,并且这个方法是从客户端调用的。
正如您可以阅读代码中的注释,我犯了一个错误,一个非常人性化的东西,我正在使用错误的变量来绑定最后一个参数,我告诉它将它绑定为一个整数,而实际上是字符串(它是登录而不是id)。但由于某种原因,即使我告诉在失败时抛出异常也没有这样的异常,但最糟糕的是提交返回true ...为什么?我花了一些宝贵的时间才发现这个错误,因为PDO并没有告诉我任何相关信息。有办法处理这些错误吗?
答案 0 :(得分:0)
当您这样做时,PDO不会抛出,因为这些输入参数对您来说是指定类型的coerced。就数据库而言,不会发生错误,因为它接收列数据类型的有效值。
这种行为在整个PHP中很普遍,因为替代方案是这段代码不起作用:
$foo = "4"; // not techically an int
$pstmt->bindParam(3, $foo, PDO::PARAM_INT);
$pstmt->execute();
如果要强制绑定参数的匹配类型,则必须手动检查(例如,使用PDOStatement::bindParam
的{{1}}包装,并将结果与指定的类型进行比较。
答案 1 :(得分:0)
没有错误,因为没有错误。
$pstmt->bindParam(3, $usu_login, PDO::PARAM_INT);
$usu_login
被强制转换为int并绑定为参数3,它创建了一个查询行:
UPDATE ... WHERE idusuario = 0
执行时,没有任何反应,因为WHERE
条件不适用于任何事情(大概)。 PDO::PARAM_INT
不会导致错误,因为它只是确保参数绑定为int,并且查询本身完全正常,即使它什么都不做(这是一个完全有效的结果)。
您可能需要检查$pstmt->rowCount()
以查看受影响的行数是否符合您的预期。