Skip to content

Commit a6566e7

Browse files
committed
Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4: Fix phpGH-20214: PDO::FETCH_DEFAULT unexpected behavior with PDOStatement::setFetchMode (php#21434)
2 parents 49a74a8 + 7bd27e7 commit a6566e7

3 files changed

Lines changed: 71 additions & 1 deletion

File tree

NEWS

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 8.5.7
44

5-
5+
- PDO:
6+
. Fixed bug GH-20214 (PDO::FETCH_DEFAULT unexpected behavior with
7+
setFetchMode). (iliaal)
68

79
07 May 2026, PHP 8.5.6
810

ext/pdo/pdo_stmt.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1630,6 +1630,10 @@ bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, zend_long mode, uint32_t mode_a
16301630

16311631
flags = mode & PDO_FETCH_FLAGS;
16321632

1633+
if ((mode & ~PDO_FETCH_FLAGS) == PDO_FETCH_USE_DEFAULT) {
1634+
mode = stmt->dbh->default_fetch_type | flags;
1635+
}
1636+
16331637
if (!pdo_verify_fetch_mode(stmt->default_fetch_type, mode, mode_arg_num, false)) {
16341638
return false;
16351639
}

ext/pdo/tests/gh20214.phpt

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
--TEST--
2+
GH-20214 (PDO::FETCH_DEFAULT unexpected behavior with PDOStatement::setFetchMode)
3+
--EXTENSIONS--
4+
pdo
5+
--SKIPIF--
6+
<?php
7+
$dir = getenv('REDIR_TEST_DIR');
8+
if (false == $dir) die('skip no driver');
9+
require_once $dir . 'pdo_test.inc';
10+
PDOTest::skip();
11+
?>
12+
--FILE--
13+
<?php
14+
if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.__DIR__ . '/../../pdo/tests/');
15+
require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
16+
$db = PDOTest::factory();
17+
18+
$db->exec('CREATE TABLE gh20214 (c1 VARCHAR(10), c2 VARCHAR(10))');
19+
$db->exec("INSERT INTO gh20214 VALUES ('v1', 'v2')");
20+
21+
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
22+
23+
// setFetchMode with FETCH_DEFAULT should use connection default (FETCH_OBJ)
24+
$stmt = $db->query('SELECT c1, c2 FROM gh20214');
25+
$stmt->setFetchMode(PDO::FETCH_DEFAULT);
26+
$row = $stmt->fetch();
27+
var_dump($row instanceof stdClass);
28+
var_dump($row->c1);
29+
30+
// fetch with FETCH_DEFAULT should also use connection default
31+
$stmt = $db->query('SELECT c1, c2 FROM gh20214');
32+
$row = $stmt->fetch(PDO::FETCH_DEFAULT);
33+
var_dump($row instanceof stdClass);
34+
35+
// fetchAll with FETCH_DEFAULT should also use connection default
36+
$stmt = $db->query('SELECT c1, c2 FROM gh20214');
37+
$rows = $stmt->fetchAll(PDO::FETCH_DEFAULT);
38+
var_dump($rows[0] instanceof stdClass);
39+
40+
// setFetchMode then fetch without argument
41+
$stmt = $db->query('SELECT c1, c2 FROM gh20214');
42+
$stmt->setFetchMode(PDO::FETCH_DEFAULT);
43+
$row = $stmt->fetch();
44+
var_dump($row instanceof stdClass);
45+
46+
// query() with FETCH_DEFAULT as second argument
47+
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_NUM);
48+
$stmt = $db->query('SELECT c1, c2 FROM gh20214', PDO::FETCH_DEFAULT);
49+
$row = $stmt->fetch();
50+
var_dump(is_array($row) && isset($row[0]));
51+
?>
52+
--CLEAN--
53+
<?php
54+
require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
55+
$db = PDOTest::factory();
56+
PDOTest::dropTableIfExists($db, "gh20214");
57+
?>
58+
--EXPECT--
59+
bool(true)
60+
string(2) "v1"
61+
bool(true)
62+
bool(true)
63+
bool(true)
64+
bool(true)

0 commit comments

Comments
 (0)