From c849b0e3e50a0e49db629bee0e20aa98404cf271 Mon Sep 17 00:00:00 2001 From: Javakky Date: Tue, 20 Jan 2026 17:59:48 +0900 Subject: [PATCH] feat: Support PDO::FETCH_KEY_PAIR --- src/FakePdoStatementTrait.php | 34 +++++++++++++++++++++++++++++ tests/EndToEndTest.php | 40 +++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/src/FakePdoStatementTrait.php b/src/FakePdoStatementTrait.php index ce33ca36..dcf0de17 100644 --- a/src/FakePdoStatementTrait.php +++ b/src/FakePdoStatementTrait.php @@ -508,6 +508,40 @@ function ($row) use ($fetch_argument, $ctor_args) { ); } + if ($fetch_style === \PDO::FETCH_KEY_PAIR) { + if (!$this->result) { + return []; + } + + /** @var array $output */ + $output = []; + + foreach ($this->result as $row) { + if ($this->conn->shouldStringifyResult()) { + $row = self::stringify($row); + } + + /** @var list $values */ + $values = \array_values($row); + + if (\count($values) < 2) { + throw new \PDOException('PDO::FETCH_KEY_PAIR requires at least two columns'); + } + + $key = $values[0]; + + if (\is_int($key) || \is_string($key)) { + $output[$key] = $values[1]; + } elseif ($key === null) { + $output[''] = $values[1]; + } else { + $output[(int) $key] = $values[1]; + } + } + + return $output; + } + throw new \Exception('Fetch style not implemented'); } diff --git a/tests/EndToEndTest.php b/tests/EndToEndTest.php index d2cd95a3..96f6cde8 100644 --- a/tests/EndToEndTest.php +++ b/tests/EndToEndTest.php @@ -95,6 +95,46 @@ public function testSelectFetchAssoc() ); } + public function testSelectFetchKeyPair() + { + $pdo = self::getConnectionToFullDB(); + + $query = $pdo->prepare("SELECT id, name FROM `video_game_characters` WHERE `id` > :id ORDER BY `id` ASC"); + $query->bindValue(':id', 14); + $query->execute(); + + $this->assertSame( + [ + '15' => 'link', + '16' => 'dude' + ], + $query->fetchAll(\PDO::FETCH_KEY_PAIR) + ); + } + + public function testSelectFetchKeyPairWithVariousKeyTypes() + { + $pdo = self::getConnectionToFullDB(false); + + $query = $pdo->prepare( + "SELECT 1.5, 'foo' + UNION ALL SELECT NULL, 'bar' + UNION ALL SELECT false, 'baz' + UNION ALL SELECT 2, 'qux'" + ); + $query->execute(); + + $this->assertEqualsCanonicalizing( + [ + 1 => 'foo', // 1.5 -> 1 + '' => 'bar', // NULL -> '' + 0 => 'baz', // false -> 0 + 2 => 'qux', // 2 -> 2 + ], + $query->fetchAll(\PDO::FETCH_KEY_PAIR) + ); + } + public function testSelectFetchAssocConverted() { $pdo = self::getConnectionToFullDB(false);