[php-src] Issue #20214: PDO::FETCH_DEFAULT unexpected behavior with PDOStatement::setFetchMode
| From: | AllenJB | Date: | Sat, 18 Oct 2025 13:03:50 +0000 |
| Subject: | [php-src] Issue #20214: PDO::FETCH_DEFAULT unexpected behavior with PDOStatement::setFetchMode | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-251082@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/20214
Author: AllenJB
### Description
As you can see in the below test, when used with ->setFetchMode, PDO::FETCH_DEFAULT changes the
fetch mode.
I would expect it to either not change the fetch mode (or to fail with an error).
The following code: https://3v4l.org/1sLR3H#v8.4.13
```php
error_reporting(E_ALL);
$db = new PDO("sqlite::memory:");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$expectedFetchMode = \PDO::FETCH_OBJ;
$db->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, $expectedFetchMode);
print "Original (expected):\n";
$stmt = $db->query("SELECT 'v1' AS c1, 'v2' AS c2");
print_r($stmt->fetch());
print "\nPDOStatement::setFetchMode:\n";
$stmt = $db->query("SELECT 'v1' AS c1, 'v2' AS c2");
$stmt->setFetchMode(\PDO::FETCH_DEFAULT);
print_r($stmt->fetch());
print "\nPDOStatement::fetch:\n";
$stmt = $db->query("SELECT 'v1' AS c1, 'v2' AS c2");
print_r($stmt->fetch(\PDO::FETCH_DEFAULT));
print "\nPDOStatement::fetchAll:\n";
$stmt = $db->query("SELECT 'v1' AS c1, 'v2' AS c2");
print_r($stmt->fetchAll(\PDO::FETCH_DEFAULT));
print "\nPDO::setAttribute:\n";
try {
$db->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_DEFAULT);
} catch (ValueError $e) {
print "Could not set fetch mode using PDO::setAttribute: ". $e->getMessage()
."\n";
}
if ($db->getAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE) !== $expectedFetchMode) {
print __LINE__ ." Fetch mode changed\n";
}
print "Done!\n";
```
Resulted in this output:
```
Original (expected):
stdClass Object
(
[c1] => v1
[c2] => v2
)
PDOStatement::setFetchMode:
Array
(
[c1] => v1
[0] => v1
[c2] => v2
[1] => v2
)
PDOStatement::fetch:
stdClass Object
(
[c1] => v1
[c2] => v2
)
PDOStatement::fetchAll:
Array
(
[0] => stdClass Object
(
[c1] => v1
[c2] => v2
)
)
PDO::setAttribute:
Could not set fetch mode using PDO::setAttribute: Fetch mode must be a bitmask of PDO::FETCH_*
constants
Done!
```
But I expected this output instead:
```
Original (expected):
stdClass Object
(
[c1] => v1
[c2] => v2
)
PDOStatement::setFetchMode:
stdClass Object
(
[c1] => v1
[c2] => v2
)
PDOStatement::fetch:
stdClass Object
(
[c1] => v1
[c2] => v2
)
PDOStatement::fetchAll:
Array
(
[0] => stdClass Object
(
[c1] => v1
[c2] => v2
)
)
PDO::setAttribute:
Could not set fetch mode using PDO::setAttribute: Fetch mode must be a bitmask of PDO::FETCH_*
constants
Done!
```
### PHP Version
```plain
PHP 8.4.11 (cli) (built: Jul 29 2025 18:02:29) (NTS Visual C++ 2022 x64)
Copyright (c) The PHP Group
Zend Engine v4.4.11, Copyright (c) Zend Technologies
and
PHP 8.4.12 (cli) (built: Sep 26 2025 19:22:55) (ZTS)
Copyright (c) The PHP Group
Zend Engine v4.4.12, Copyright (c) Zend Technologies
with Zend OPcache v8.4.12, Copyright (c), by Zend Technologies
(and 3v4l PHP 8.4.13)
```
### Operating System
n/a