Как проверить PHP, если предоставлено больше параметров PDO, чем необходимо - PullRequest
2 голосов
/ 05 мая 2020

У меня есть следующий фрагмент кода (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 (первый отчет с 20 января 2019 г.)

Ответы [ 2 ]

3 голосов
/ 05 мая 2020

Вы правы, эта ситуация не вызывает ни исключений, ни ошибок. 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);
}

Не идеально, но ...

0 голосов
/ 05 мая 2020

Чтобы проверить, какие параметры были предоставлены, используйте это: https://www.php.net/manual/en/pdostatement.debugdumpparams.php,
Также используйте привязки параметров, чтобы быть абсолютно уверенным, что вы связали параметры правильно: https://www.php.net/manual/en/pdostatement.bindparam.php

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...