Skip to content

PDO::FETCH_DEFAULT unexpected behavior with PDOStatement::setFetchMode #20214

@AllenJB

Description

@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

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

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions