skip to Main Content

I use PDOStatement::fetchAll with FETCH_GROUP and FETCH_ASSOC to get my table’s primary key as the array key.

$objects = $stmt_obj->fetchAll(PDO::FETCH_GROUP | PDO::FETCH_CLASS);

This leads to the following result:


Array
(
    [56] => Array
        (
            [0] => stdClass Object
                (
                    ...
                )
        )

    [39] => Array
        (
            [0] => stdClass Object
                (
                    ...
                )
        )

    [38] => Array
        (
            [0] => stdClass Object
                (
                    ...
                )
        )

    [71] => Array
        (
            [0] => stdClass Object
                (
                    ...
                )
        )
)

To strip the result of the useless numbered array I used

$objects = array_Map('reset', $objects);

As described here:
https://www.php.net/manual/en/pdostatement.fetchall.php#88699
or here:
https://gist.github.com/betweenbrain/9239337

In PHP 8.2 I get a warning:

PHP Warning:  reset(): Argument #1 ($array) must be passed by reference, value given

What other way can I use to get get rid of the useless numbered array and get the following result:

Array
(
    [56] => stdClass Object
        (
            ...
        )

    [39] => stdClass Object
        (
            ...

    [38] => stdClass Object
        (
            ...
        )

    [71] => stdClass Object
        (
            ...
        )
)

2

Answers


  1. There’s no need to map over the array. Add the PDO::FETCH_UNIQUE flag and the result will have each element as a single object, rather than an array of objects.

    $objects = $stmt_obj->fetchAll(PDO::FETCH_GROUP | PDO::FETCH_CLASS | PDO::FETCH_UNIQUE);
    

    See this example in the documentation.

    Login or Signup to reply.
  2. When you pass reset directly as the callback function to array_map, you are attempting to use reset on each element of the $objects array. However, reset expects its argument to be passed by reference because it potentially modifies the array by resetting its internal pointer to the first element. So you can use either anonymous function (closure) with reset inside it or current which does not require passing array by reference.

    $objects = [
        56 => [new stdClass()],
        39 => [new stdClass()],
        38 => [new stdClass()],
    ];
    print_r($objects);
    
    $new_array_using_reset = array_map(static fn (array $array) => reset($array), $objects);
    print_r($new_array_using_reset);
    
    $new_array_using_current = array_map('current', $objects);
    print_r($new_array_using_current);
    

    output:

    $objects:

    Array
    (
        [56] => Array
            (
                [0] => stdClass Object
                    (
                    )
    
            )
    
        [39] => Array
            (
                [0] => stdClass Object
                    (
                    )
    
            )
    
        [38] => Array
            (
                [0] => stdClass Object
                    (
                    )
    
            )
    
    )
    

    $new_array (using reset or current:

    Array
    (
        [56] => stdClass Object
            (
            )
    
        [39] => stdClass Object
            (
            )
    
        [38] => stdClass Object
            (
            )
    
    )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search