我试图强制PDO在绑定变量的数量大于查询中的params数时抛出异常。我不喜欢使用原生的准备陈述。
如果我使用模拟的准备(PDO::ATTR_EMULATE_PREPARES => true
),异常工作正常,我使用此代码测试:
$Pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = 'SELECT id
FROM my_table
WHERE
doc = :doc';
try {
$Ps = $Pdo->prepare($sql, array(PDO::ATTR_EMULATE_PREPARES => true));
$result = $Ps->execute(array(
':doc' => '1234',
':name' => 'Myself'
));
} catch (PDOException $e) {
throw new \Exception('Query failed: ' . $e->getMessage());
}
抛出:
Fatal error: Uncaught exception 'Exception' with message 'Query failed: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens'
但如果我将PDO::ATTR_EMULATE_PREPARES
更改为false
,则不会抛出异常,我只会在false
中收到$result
。出于安全原因,我也想在这种情况下强制例外,但我没有看到如何达到这一点。欢迎任何建议。
编辑1
使用PDO::ATTR_EMULATE_PREPARES => false
,如果我执行var_dump($Ps->errorInfo())
我得到:
array(3) {
[0]=>
string(5) "HY093"
[1]=>
int(7)
[2]=>
string(0) ""
}
答案 0 :(得分:2)
首先,如果我们尝试执行一个超出参数的预准备语句,PostgreSQL本身就会出错。
psql演示:
test=> prepare p as select 1+$1;
PREPARE
test=> execute p(1);
?column?
----------
2
(1 row)
test=> execute p(1,2);
ERROR: wrong number of parameters for prepared statement "p"
DETAIL: Expected 1 parameters but got 2.
当使用带有真实预处理语句的PHP / PDO时,即使在将查询传递给postgres之前,PDO层本身也应该出错(准备是延迟的,在另一个问题中提到了更多细节:PHP Postgres PDO driver does not support prepared statement?)
使用PHP 5.3.10-1ubuntu3.15,PG 9.1(Ubuntu 12.04)进行演示
<?
$pdo = new PDO('pgsql:dbname=test');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$query = "SELECT 1+:foo";
try {
$stmt = $pdo->prepare($query);
$stmt->execute(array(":foo"=>1 ,":other"=>2));
var_dump($stmt->fetchAll());
}
catch(PDOException $e){
echo "Error ". $e->getMessage() ."\n";
}
?>
这会产生:
错误SQLSTATE [HY093]:参数号无效::其他
作为比较点,用
进行相同的测试$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
(模拟的预准备语句)产生错误,并带有不同的错误消息,问题中提到的错误消息:
错误SQLSTATE [HY093]:参数号无效:绑定数 变量与令牌数量不匹配
确保您使用的是最新版本的PHP / PDO。