Using value of a column as index in results using PDO

Solution 1:

Although PDO::FETCH_UNIQUE description in PHP manual is quite unclear, but in fact it's exact parameter you actually need.

$data = $pdo->query('SELECT * FROM table')->fetchAll(PDO::FETCH_UNIQUE);

is giving you an array indexed by the field listed in SELECT clause first (when * is used then first field in the table definition, which should be id in your case).

Note that by default using just PDO::FETCH_UNIQUE will give you resulting rows with doubled values. You can either add preferred row mode to this call or - better, set it once for all PDO calls in constructor or via setAttribute(). The output below is shown for PDO::FETCH_ASSOC set as default fetch mode.

  1 => array (
    'name' => 'Solidfloor',
    'url' => 'solidfloor',
  ),
  2 => array (
    'name' => 'Quickstep',
    'url' => 'quickstep',
  ),
  4 => array (
    'name' => 'Cleanfloor',
    'url' => 'cleanfloor',
  ),
)

Solution 2:

Fetch as assoc

For the manual: http://php.net/manual/en/pdostatement.fetchall.php

fetch_style

Controls the contents of the returned array as documented in PDOStatement::fetch(). Defaults to value of PDO::ATTR_DEFAULT_FETCH_MODE (which defaults to PDO::FETCH_BOTH)

To return an array consisting of all values of a single column from the result set, specify PDO::FETCH_COLUMN. You can specify which column you want with the column-index parameter.

To fetch only the unique values of a single column from the result set, bitwise-OR PDO::FETCH_COLUMN with PDO::FETCH_UNIQUE.

To return an associative array grouped by the values of a specified column, bitwise-OR PDO::FETCH_COLUMN with PDO::FETCH_GROUP.

That last bit is key. It doesn't seem to be completely documented (that I could find), but instead of PDO::FETCH_COLUMN, you can combine PDO::FETCH_ASSOC with PDO::FETCH_GROUP to achieve the desired result:

$PDOstmt->fetchAll(PDO::FETCH_ASSOC | PDO::FETCH_GROUP)

So, given the above data:

$stmt = $PDO_obj->prepare('select * from brands');
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC | PDO::FETCH_GROUP);
d($result);

Results in:

array (6) [
    '1' => array (1) [
        array (2) [
            'name' => string (10) "Solidfloor"
            'url' => string (10) "solidfloor"
        ]
    ]
    '2' => array (1) [
        array (2) [
            'name' => string (9) "Quickstep"
            'url' => string (9) "quickstep"
        ]
    ]
    '4' => array (1) [
        array (2) [
            'name' => string (10) "Cleanfloor"
            'url' => string (10) "cleanfloor"
        ]
    ]
    '5' => array (1) [
        array (2) [
            'name' => string (12) "Blue Dolphin"
            'url' => string (12) "blue-dolphin"
        ]
    ]
    '6' => array (1) [
        array (2) [
            'name' => string (5) "Krono"
            'url' => string (5) "krono"
        ]
    ]
    '8' => array (1) [
        array (2) [
            'name' => string (7) "Meister"
            'url' => string (7) "meister"
        ]
    ]
]

( d() is just a handy debugging function from the kint library, like var_dump() or print_r() )

Note that the column used to index the array will always be the first column in the results, so you can modify your select statement to choose which column you want. And note also that the indexed column will be stripped out of each row's array; to get around that, you can add the column twice to your select statement (i.e., select id, brands.* from brands, etc.).

There are more parameters documented here: http://php.net/manual/en/pdostatement.fetch.php , like PDO::FETCH_UNIQUE to make sure that each index is used only once.