Commit 3580bbd28b6 for php.net
commit 3580bbd28b6033b0d15b67e23b9b63c7b3390228
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date: Mon Aug 24 12:40:21 2026 -0400
ext/pdo: Do not register a bindColumn() binding for an unknown column
really_register_bound_param() raised the implementation error for a column
name that is not in the result set and then registered the binding anyway,
so bindColumn() returned true for a binding that can never fire, and
repeated failing calls with distinct names grew bound_columns without
bound. Refuse the binding in every error mode instead.
Closes GH-23799
diff --git a/NEWS b/NEWS
index 95e545f919a..3587344ca1b 100644
--- a/NEWS
+++ b/NEWS
@@ -57,6 +57,8 @@ PHP NEWS
- PDO:
. Fixed PDOStatement::getColumnMeta() reading out of bounds for an invalid
column index. (Ilia Alshanetsky)
+ . Fixed PDOStatement::bindColumn() registering a binding for a column name
+ that is not in the result set. (Ilia Alshanetsky)
- Readline:
. Fixed a heap over-read in the interactive shell prompt when cli.prompt is
diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c
index 8612a01e044..97d1a058fd5 100644
--- a/ext/pdo/pdo_stmt.c
+++ b/ext/pdo/pdo_stmt.c
@@ -311,6 +311,7 @@ static bool really_register_bound_param(struct pdo_bound_param_data *param, pdo_
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);
+ return 0;
}
}
diff --git a/ext/pdo/tests/pdo_bindcolumn_unknown_column.phpt b/ext/pdo/tests/pdo_bindcolumn_unknown_column.phpt
new file mode 100644
index 00000000000..44e85ec07c3
--- /dev/null
+++ b/ext/pdo/tests/pdo_bindcolumn_unknown_column.phpt
@@ -0,0 +1,41 @@
+--TEST--
+PDO: bindColumn() must fail for a column name that is not in the result set
+--EXTENSIONS--
+pdo
+--SKIPIF--
+<?php
+$dir = getenv('REDIR_TEST_DIR');
+if (false == $dir) die('skip no driver');
+require_once $dir . 'pdo_test.inc';
+PDOTest::skip();
+?>
+--FILE--
+<?php
+if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.__DIR__ . '/../../pdo/tests/');
+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;
+}
+?>
+--CLEAN--
+<?php
+if (getenv('PDOTEST_DSN') === 'sqlite::memory:') return;
+
+require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
+$db = PDOTest::factory();
+$db->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