|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2018-07-19 15:11 UTC] requinix@php.net
Description: ------------ From bug #76639. If PDO is not emulating prepares and a query contains named parameters, SELECT a FROM b WHERE c = :param OR d = :param it will get rewritten to use placeholders SELECT a FROM b WHERE c = ? OR d = ? When the user executes the query they will only provide one value, and that results in an error because the query requires two values. MySQL/pdo_mysql gives "SQLSTATE[HY093]: Invalid parameter number", which is technically correct but only understandable if the user knows about the rewriting. It also happens during the call to execute(), which is misleading as the problem was actually in the prepared statement given to prepare(). The docs for PDO::prepare() do speak of this: > You cannot use a named parameter marker of the same name more than once in a prepared statement, unless > emulation mode is on. The request: Since PDO is parsing and rewriting queries during prepare(), it can recognize this situation happening and so should present a meaningful error message/exception at that time. Test script: --------------- <?php $pdo = new PDO(...); $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $pdo->prepare("SELECT :param, :param"); ?> Expected result: ---------------- Some appropriate error message or PDOException during $pdo->prepare(). Actual result: -------------- Query is accepted and prepared even though it can't be executed. PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Nov 05 14:00:01 2025 UTC |
> If PDO is not emulating prepares and a query contains named parameters, > SELECT a FROM b WHERE c = :param OR d = :param > > it will get rewritten to use placeholders > SELECT a FROM b WHERE c = ? OR d = ? This is driver specific. If the driver supports either parameter style (e.g. PDO_SQLite), there is no need to call pdo_parse_params(), so the query won't be rewritten. > Some appropriate error message or PDOException during > $pdo->prepare(). Maybe we should generally emit a notice if the query is rewritten? Otherwise the following code will successfully execute with emulated prepares, but not with native prepares (PDO_MySQL, PHP-7.4): <?php $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, $emulate); $stmt = $pdo->prepare('SELECT :a as foo, :b as bar'); $stmt->execute([1, 2]); ?> Or is this a particular glitch of PDO_MySQL?