有没有办法获取按PDO指定列的值分组的关联数组?

Hon*_*ong 24 php arrays pdo fetch

例如,让我们使用一些简单的数据集

+---------+------+------+------------+
| name    | age  | sex  | position   |
+---------+------+------+------------+
| Antony  |   34 | M    | programmer |
| Sally   |   30 | F    | manager    |
| Matthew |   28 | M    | designer   |
+---------+------+------+------------+
Run Code Online (Sandbox Code Playgroud)

我们想要得到的是以这种方式组织阵列

Array
(
  [Antony] => Array
    (
      [age] => 34
      [sex] => M
      [position] => programmer
    )

  [Sally] => Array
    (
      [age] => 30
      [sex] => F
      [position] => manager
    )

  [Matthew] => Array
    (
      [age] => 28
      [sex] => M
      [position] => designer
    )
)
Run Code Online (Sandbox Code Playgroud)

作为粗略的近似,我们可以使用

$pdo->query('SELECT * FROM employee')->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_ASSOC);
Run Code Online (Sandbox Code Playgroud)

但结果我们有不必要的嵌套级别

Array
(
    [Antony] => Array
        (
            [0] => Array
                (
                    [age] => 34
                    [sex] => M
                    [position] => programmer
                )

        )

    [Sally] => Array
        (
            [0] => Array
                (
                    [age] => 30
                    [sex] => F
                    [position] => manager
                )

        )

    [Matthew] => Array
        (
            [0] => Array
                (
                    [age] => 28
                    [sex] => M
                    [position] => designer
                )

        )

)
Run Code Online (Sandbox Code Playgroud)

我试图通过使用回调函数摆脱这种不必要的嵌套级别

$stmt->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_ASSOC|PDO::FETCH_FUNC, 'current');
Run Code Online (Sandbox Code Playgroud)

但由于某些原因它没有通过

Array
  (
   [0] => Array
    (
        [age] => 34
        [sex] => M
        [position] => programmer
    )
  ) 
Run Code Online (Sandbox Code Playgroud)

但只是一堆标量34, 'M', 'programmer'回调功能:(

您可以使用回调等功能查看它

function what_do_you_pass_me() {

  $numargs = func_num_args();
  $arg_list = func_get_args();
  for ($i = 0; $i < $numargs; $i++) {
    echo "Argument $i is: " . $arg_list[$i] . "\n";
  };
  echo "\n\n";
};
Run Code Online (Sandbox Code Playgroud)

那么有没有一种方法可以在PDO::FETCH_*不使用array_map('current', $result)获取结果后使用模式获得所需的结果集?

imc*_*iac 55

这是一个很老的话题,但我找到了非常简单的解决方案:

->fetchAll(\PDO::FETCH_GROUP|\PDO::FETCH_UNIQUE)
Run Code Online (Sandbox Code Playgroud)

第一个col将被设置为key,rest将被设置为value.

无需遍历数组或使用array_map.

  • @Gideon简短的回答是避免任何[Namespace](http://www.php.net/manual/en/language.namespaces.php)冲突.像这样的常量前面的\将使用全局命名空间.在这种情况下,我们不确定代码将在何处结束,如果将代码放入除全局代码之外的命名空间中的类中,则在常量前面使用\编写是安全的.Stack Overflow和其他地方的常见做法是保留\ out,因为它取决于最终实现. (5认同)
  • FETCH_GROUP包括什么?当然只使用FETCH_UNIQUE就能达到理想的效果 - 这就是FETCH_UNIQUE的重点. (4认同)
  • PDO前面有什么斜线::这里是为了什么? (3认同)
  • @BradKent我建议你测试一下.`var_dump((PDO :: FETCH_GROUP | PDO :: FETCH_UNIQUE)=== PDO :: FETCH_UNIQUE); //真 (2认同)
  • @BradKent 真的吗?你肯定有这样的说法的证据吗? (2认同)

小智 13

减少不必要的嵌套数组级别:

$res = $pdo->query('SELECT * FROM employee')->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_ASSOC);
$res = array_map('reset', $res);
Run Code Online (Sandbox Code Playgroud)

  • 从`query`的结果调用`fetchAll`是不安全的,因为`query`可以返回false.当PHP尝试在非对象上调用方法时,这将导致致命错误. (3认同)

小智 11

键关联数组

PDO::FETCH_GROUP|PDO::FETCH_UNIQUE|PDO::FETCH_ASSOC
Run Code Online (Sandbox Code Playgroud)

  • **说明:**`FETCH_ASSOC`获取字段为`column_name => value`,`GROUP`获取第1列并使其成为结果数组的主键,但它仍然是单项数组的数组***(假设结果集中每个主键只有1个项目)*** - `UNIQUE`删除不需要的级别,基本上说"嘿伙计,每个主键只有1项 - 所以整理!:) ". (2认同)

You*_*nse 10

接受的答案基本上是一个货物崇拜代码,它只是偶然地完成它的工作,但它本身没有任何意义.

PDO::FETCH_GROUP并且PDO::FETCH_UNIQUE是互斥的获取模式,不能一起使用.只有其中一个可以工作.当你将它们组合起来时,后者接管并且\PDO::FETCH_GROUP|\PDO::FETCH_UNIQUE实际上只是PDO::FETCH_UNIQUE.

除此之外,问题本身是模糊的,OP希望他的数组被唯一字段索引,而他称之为分组,这也引起了答案中的争议.

所以说实话:

在这两种情况下,必须首先在SELECT字段列表中列出要用作第一级数组索引的字段.

关于的一个注释PDO::FETCH_ASSOC.鉴于首选结果格式的获取模式可以在构造函数中为所有结果设置一次,因此将其明确列出也没有意义.