diff --git a/UPGRADING b/UPGRADING index 5d551005042e..27dc06f12d2e 100644 --- a/UPGRADING +++ b/UPGRADING @@ -19,6 +19,11 @@ PHP 8.7 UPGRADE NOTES 1. Backward Incompatible Changes ======================================== +- PDO: + . PDOStatement::bindColumn() now throws a ValueError when the column name is + not present in the result set. It previously reported the condition + through PDO::ATTR_ERRMODE and returned false. + - Standard: . The number of filters that can be chained in a php://filter URL is limited to 16 by default. Set the stream context option max_filter_count to change diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 1e9e1052d282..9774b197b7d9 100644 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -295,12 +295,7 @@ static bool really_register_bound_param(struct pdo_bound_param_data *param, pdo_ /* if you prepare and then execute passing an array of params keyed by names, * then this will trigger, and we don't want that */ if (param->paramno == -1) { - /* Should this always be an Error? */ - char *tmp; - /* TODO Error? */ - spprintf(&tmp, 0, "Did not find column name '%s' in the defined columns; it will not be bound", ZSTR_VAL(param->name)); - pdo_raise_impl_error(stmt->dbh, stmt, "HY000", tmp); - efree(tmp); + zend_argument_value_error(1, "must refer to a column present in the result set, \"%s\" given", ZSTR_VAL(param->name)); return false; } } diff --git a/ext/pdo/tests/pdo_bindcolumn_unknown_column.phpt b/ext/pdo/tests/pdo_bindcolumn_unknown_column.phpt index 44e85ec07c31..3e3ba30e8c41 100644 --- a/ext/pdo/tests/pdo_bindcolumn_unknown_column.phpt +++ b/ext/pdo/tests/pdo_bindcolumn_unknown_column.phpt @@ -1,5 +1,5 @@ --TEST-- -PDO: bindColumn() must fail for a column name that is not in the result set +PDO: bindColumn() must throw for a column name that is not in the result set --EXTENSIONS-- pdo --SKIPIF-- @@ -17,16 +17,20 @@ require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc'; $db = PDOTest::factory(); $db->exec('CREATE TABLE pdo_bindcolumn_unknown_column (name varchar(255))'); -$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); -$stmt = $db->query('SELECT name FROM pdo_bindcolumn_unknown_column'); -var_dump(@$stmt->bindColumn('nosuchcolumn', $var)); - -$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); -try { - $stmt->bindColumn('nosuchcolumn', $var); -} catch (PDOException $e) { - echo $e::class, ": ", $e->getMessage(), PHP_EOL; +// The error mode must not affect a ValueError. +foreach ([PDO::ERRMODE_SILENT, PDO::ERRMODE_WARNING, PDO::ERRMODE_EXCEPTION] as $mode) { + $db->setAttribute(PDO::ATTR_ERRMODE, $mode); + $stmt = $db->query('SELECT name FROM pdo_bindcolumn_unknown_column'); + try { + $stmt->bindColumn('nosuchcolumn', $var); + } catch (ValueError $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; + } } + +// A column that does exist still binds. +$stmt = $db->query('SELECT name FROM pdo_bindcolumn_unknown_column'); +var_dump($stmt->bindColumn('name', $var)); ?> --CLEAN-- exec('DROP TABLE pdo_bindcolumn_unknown_column'); ?> --EXPECT-- -bool(false) -PDOException: SQLSTATE[HY000]: General error: Did not find column name 'nosuchcolumn' in the defined columns; it will not be bound +ValueError: PDOStatement::bindColumn(): Argument #1 ($column) must refer to a column present in the result set, "nosuchcolumn" given +ValueError: PDOStatement::bindColumn(): Argument #1 ($column) must refer to a column present in the result set, "nosuchcolumn" given +ValueError: PDOStatement::bindColumn(): Argument #1 ($column) must refer to a column present in the result set, "nosuchcolumn" given +bool(true) diff --git a/ext/pdo_sqlite/tests/pdo_driver_options_weakref.phpt b/ext/pdo_sqlite/tests/pdo_driver_options_weakref.phpt index 16dc9a3c4666..15cafa656e70 100644 --- a/ext/pdo_sqlite/tests/pdo_driver_options_weakref.phpt +++ b/ext/pdo_sqlite/tests/pdo_driver_options_weakref.phpt @@ -19,17 +19,20 @@ var_dump($weakReference->get()); $stmt = $db->prepare('SELECT ? AS value'); $stmt->execute(); -$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); $value = null; $driverOptions = [new Tracked()]; $weakReference = WeakReference::create($driverOptions[0]); -var_dump(@$stmt->bindColumn('missing', $value, PDO::PARAM_STR, 0, $driverOptions)); -unset($driverOptions); +try { + $stmt->bindColumn('missing', $value, PDO::PARAM_STR, 0, $driverOptions); +} catch (ValueError $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} +unset($e, $driverOptions); var_dump($weakReference->get()); unset($value, $stmt); ?> --EXPECT-- bool(true) NULL -bool(false) +ValueError: PDOStatement::bindColumn(): Argument #1 ($column) must refer to a column present in the result set, "missing" given NULL