首页 > 解决方案 > 如果提供的 PDO 参数比需要的多,如何检查 PHP

问题描述

我有以下代码(PHP 7.3.16)从数据库(MySQL)中检索一些数据:

// db credentials
$dbhost = "localhost";
$dbuser = "user";
$dbpass = "password";
$dbname = "database";

// pdo
$dsn = "mysql:host=".$dbhost.";dbname=".$dbname.";charset=utf8";
$options = [
  PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
  PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
  PDO::ATTR_EMULATE_PREPARES => false
];
$pdo = new PDO($dsn, $dbuser, $dbpass, $options);

// run sql query
$sql = "SELECT * FROM foo WHERE bar > ?";

$pdo_parameters = [ 1 ];
// this will produce no results without any error:
// $pdo_parameters = [ 1, 2, 3 ];

$stmt = $pdo->prepare($sql);
$stmt->execute( $pdo_parameters );

while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
    var_dump($row);
}

如果数组$pdo_parameters只包含 1 个元素,那么一切都按预期工作,我会收到一个结果。但是,当$pdo_parameters包含多个时,我根本没有收到任何结果,没有任何异常消息。PHP 错误处于活动状态,但我没有看到任何 PDO 错误消息。为什么?

如果参数太多,我想引发 PHP 异常。那可能吗?

Fatal error: Uncaught PDOException: SQLSTATE[HY093]: Invalid parameter number in /tmp/test:42 Stack trace: #0 /tmp/test.php(42): PDOStatement->execute(Array) #1 {main} thrown in /tmp/test.php on line 42

我有一个庞大的代码库,在这种情况下需要适当的异常处理。但是我不明白为什么 PHP 在这种情况下不会引发异常。这只是另一个 PHP 错误,还是 PHP(PHP C 内部)无法检查是否有太多 PDO 参数?我知道如何用普通的 PHP 自己检查(如果我们在某些字符串中有“?”可能会非常不准确),但如果 PHP PDO 扩展具有检查这种情况的功能会更好。


编辑:这是一个已知的 PHP 错误:https ://bugs.php.net/bug.php?id=77490 (2019 年 1 月 20 日的第一份报告)

标签: phpmysqlexceptionpdo

解决方案


你是对的,这种情况似乎不会引发异常或触发错误。PDOStatement::execute()至少返回false,因此您可以自己滚动:

$dsn = "mysql:host=$dbhost;dbname=$dbname;charset=utf8mb4";
$options = [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES => false,
];
$pdo = new PDO($dsn, $dbuser, $dbpass, $options);

$sql = 'SELECT ? AS foo';
$stmt = $pdo->prepare($sql);

if (!$stmt->execute([1, 2])) {
    throw new InvalidArgumentException('Failed to execute statement');
}
while ($row = $stmt->fetch()) {
    var_dump($row);
}

不理想但...


推荐阅读