How to check in PHP if more PDO parameters provided than needed

北城以北 提交于 2020-05-29 10:20:06

问题


I have following piece of code (PHP 7.3.16) which retrieves some data from database (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);
}

If array $pdo_parameters contains only 1 element then everything works as expected and I receive a result. However when $pdo_parameters contains more than one I don't receive any results at all without any exception message. PHP errors are active, but I don't see any PDO error message. Why?

I would like to raise an PHP exception if there are too many parameters. Is that possible?

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

I have a huge code base and need in such cases a proper exception handling. However I don't understand why PHP doesn't raise an exception in that case. Is this just another PHP bug or if there is just no way for PHP (PHP C internals) to check if there are too many PDO parameters? I know how to check that by myself in plain PHP (could be pretty inaccurate though if we have "?" in some strings), but it would be better if PHP PDO extension would have a function to check such cases.


EDIT: It is a known PHP bug: https://bugs.php.net/bug.php?id=77490 (first report from 20 January 2019)


回答1:


You're right, that situation doesn't seem to throw exceptions nor trigger errors. PDOStatement::execute() at least returns false so you can roll your own:

$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);
}

Not ideal but...




回答2:


To check what param were provided use this: https://www.php.net/manual/en/pdostatement.debugdumpparams.php,
Also use param bindings to be absolutely sure that you have bind the params the right way: https://www.php.net/manual/en/pdostatement.bindparam.php



来源:https://stackoverflow.com/questions/61617834/how-to-check-in-php-if-more-pdo-parameters-provided-than-needed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!