diff --git a/src/Pg.php b/src/Pg.php index e8d7aff..7c0f5a6 100644 --- a/src/Pg.php +++ b/src/Pg.php @@ -460,6 +460,12 @@ protected function replaceBind(string &$preparedQuery, Bind $bind): void } /** + * Replaces named placeholder with its value. + * + * Trailing (\W|$) keeps :id from being replaced inside :idAccount, but, + * unlike a mandatory (\W), matches a placeholder standing at the very end + * of the query as well. + * * @param $name * @param $value * @param $subject @@ -467,7 +473,7 @@ protected function replaceBind(string &$preparedQuery, Bind $bind): void */ private function _replaceBind($name, $value, $subject) { - return preg_replace('~' . $name . '(::\w+)?(\W)~', sprintf("%s$1$2", $value), $subject); + return preg_replace('~' . $name . '(::\w+)?(\W|$)~', sprintf("%s$1$2", $value), $subject); } /** diff --git a/tests/Pg/PgBindTest.php b/tests/Pg/PgBindTest.php index 5eee331..1aa5168 100644 --- a/tests/Pg/PgBindTest.php +++ b/tests/Pg/PgBindTest.php @@ -98,4 +98,43 @@ public function testBind() self::assertSame('1.00011122', $row['sixes']); self::assertSame('{foo,bar,false,NULL}', $row['array_of_text']); } + + /** + * Placeholder standing at the very end of the query must be replaced too. + * + * @throws DBDException + * @throws Exception + */ + public function testBindAtTheEndOfQuery() + { + $sth = $this->db->prepare("SELECT :int AS num WHERE 'some string' = :string"); + $sth->bind(':int', 1, NumericPrimitives::Int16) + ->bind(':string', 'some string'); + + $sth->execute(); + $row = $sth->fetchRow(); + + self::assertIsArray($row); + self::assertEquals(1, $row['num']); + } + + /** + * Shorter bind name must not be replaced inside a longer one. + * + * @throws DBDException + * @throws Exception + */ + public function testBindNameIsPrefixOfAnother() + { + $sth = $this->db->prepare("SELECT :id AS first, :idAccount AS second"); + $sth->bind(':id', 'one') + ->bind(':idAccount', 'two'); + + $sth->execute(); + $row = $sth->fetchRow(); + + self::assertIsArray($row); + self::assertSame('one', $row['first']); + self::assertSame('two', $row['second']); + } }