From 9f790afa2ecbe4287c51102e96ef24b1337e45e9 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Sat, 18 Oct 2025 18:15:36 +0100 Subject: [PATCH] Fix MysqliStatement to work with named params --- Tests/Mysqli/MysqliPreparedStatementTest.php | 45 +++++++++++++++++++- src/Mysqli/MysqliStatement.php | 5 ++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/Tests/Mysqli/MysqliPreparedStatementTest.php b/Tests/Mysqli/MysqliPreparedStatementTest.php index 34fe60a7..38d73d56 100644 --- a/Tests/Mysqli/MysqliPreparedStatementTest.php +++ b/Tests/Mysqli/MysqliPreparedStatementTest.php @@ -51,6 +51,14 @@ protected function setUp(): void ) ); } + + $insertQuery = 'INSERT INTO dbtest (title, description, start_date) VALUES (:title, :description, :start_date)'; + $mysqliStatementObject = new MysqliStatement(static::$connection->getConnection(), $insertQuery); + $mysqliStatementObject->execute([ + ':title' => 'Test Title', + ':description' => 'Test Description', + ':start_date' => '2023-01-01', + ]); } /** @@ -148,10 +156,45 @@ public function testPreparedStatementWithSingleKey() $statement = 'SELECT * FROM dbtest WHERE `title` LIKE :search OR `description` LIKE :search2'; $mysqliStatementObject = new MysqliStatement(static::$connection->getConnection(), $statement); $dummyValue = 'test'; - $dummyValue2 = 'test'; $mysqliStatementObject->bindParam(':search', $dummyValue); $mysqliStatementObject->bindParam(':search2', $dummyValue); $mysqliStatementObject->execute(); } + + /** + * Regression test to ensure running queries with bound variables still works + */ + public function testPreparedStatementWithBinding() + { + $statement = 'SELECT id FROM dbtest WHERE `title` LIKE :search'; + $mysqliStatementObject = new MysqliStatement(static::$connection->getConnection(), $statement); + $title = 'Test Title'; + $mysqliStatementObject->bindParam(':search', $title); + $mysqliStatementObject->execute(); + $result = $mysqliStatementObject->fetchColumn(); + + $title = 'changed'; + $mysqliStatementObject->execute(); + $result2 = $mysqliStatementObject->fetchColumn(); + $this->assertNotEquals($result, $result2); + } + + /** + * Regression test to ensure running queries with bound variables still works + */ + public function testPreparedStatementWithoutBinding() + { + $statement = 'SELECT id FROM dbtest WHERE `title` LIKE :search'; + $mysqliStatementObject = new MysqliStatement(static::$connection->getConnection(), $statement); + $title = 'Test Title'; + $params = [':search' => $title]; + $mysqliStatementObject->execute($params); + $result = $mysqliStatementObject->fetchColumn(); + + $params[':search'] = 'changed'; + $mysqliStatementObject->execute($params); + $result2 = $mysqliStatementObject->fetchColumn(); + $this->assertNotEquals($result, $result2); + } } diff --git a/src/Mysqli/MysqliStatement.php b/src/Mysqli/MysqliStatement.php index afda7b72..040e2cb7 100644 --- a/src/Mysqli/MysqliStatement.php +++ b/src/Mysqli/MysqliStatement.php @@ -306,7 +306,10 @@ private function bindValues(array $values) if (!empty($this->parameterKeyMapping)) { foreach ($values as $key => &$value) { - $params[$this->parameterKeyMapping[$key]] =& $value; + $paramKey = $this->parameterKeyMapping[$key]; + foreach ($paramKey as $currentKey) { + $params[$currentKey] =& $value; + } } ksort($params);