解释似乎是fetchAll() 和setFetchMode() 支持不同的PDO::FETCH__ 常量集。
我认为setFetchMode() 会忽略PDO::FETCH_GROUP,但不会忽略PDO::FETCH_ASSOC。
我从 PHP 源代码中确认了这一点,请参阅 setFetchMode() 实现。 setFetchMode 支持的常量列表不包括PDO::FETCH_GROUP。
为什么setFetchMode()和fetchAll()的结果不同
代码:
<?php
$db = new PDO('mysql:host=localhost;dbname=test', 'root');
// print the default output, no constants
$sql = "SELECT * FROM service_table";
$q = $db->query($sql);
$result = $q->fetchAll();
echo 'Result 0' . PHP_EOL;
var_dump($result);
// use fetchAll() with constants
$sql = "SELECT * FROM service_table";
$q = $db->query($sql);
$result = $q->fetchAll(PDO::FETCH_GROUP | PDO::FETCH_ASSOC);
echo 'Result 1' . PHP_EOL;
var_dump($result);
// use setFetchMode with constants
$sql = "SELECT * FROM service_table";
$q = $db->query($sql);
$q->setFetchMode(PDO::FETCH_GROUP | PDO::FETCH_ASSOC);
$result = $q->fetchAll();
echo 'Result 2' . PHP_EOL;
var_dump($result);
测试数据
mysql> select * from test.service_table;
+----+------+
| id | name |
+----+------+
| 1 | one |
| 2 | two |
+----+------+
结果 0
这是默认设置,结果不分组,并且有基于名称和基于索引的字段:
array(2) {
[0] =>
array(4) {
'id' => string(1) "1"
[0] => string(1) "1"
'name' => string(3) "one"
[1] => string(3) "one"
}
[1] =>
array(4) {
'id' => string(1) "2"
[0] => string(1) "2"
'name' => string(3) "two"
[1] => string(3) "two"
}
}
结果 1
这是$q->fetchAll(PDO::FETCH_GROUP | PDO::FETCH_ASSOC) 的结果。我们有FETCH_GROUP和FETCH_ASSOC的效果:
array(2) {
[1] => array(1) {
[0] => array(1) {
'name' => string(3) "one"
}
}
[2] => array(1) {
[0] => array(1) {
'name' => string(3) "two"
}
}
}
结果 2
这是$q->setFetchMode(PDO::FETCH_GROUP | PDO::FETCH_ASSOC);的结果,我们只有FETCH_ASSOC的效果:
array(2) {
[0] => array(2) {
'id' => string(1) "1"
'name' => string(3) "one"
}
[1] => array(2) {
'id' => string(1) "2"
'name' => string(3) "two"
}
}
这样,FETCH_GROUP 适用于 fetchAll(),但不适用于 setFetchMode()。 FETCH_ASSOC 在这两种情况下都有效。
PHP 文档
现在,来自文档的间接确认:
这里是所有PDO constants 的列表。 PDO::FETCH_FUNC 的描述说:
允许完全自定义动态处理数据的方式(仅在 PDOStatement::fetchAll() 内部有效)。
所以我们知道至少这个常量只适用于fetchAll(),并且可以假设其他常量可能并不适用于任何地方。
此外,如果我们查看 fetch() 的文档,我们会看到有限的常量列表。
例如PDO::FETCH_GROUP 和PDO::FETCH_UNIQUE 出现在fetchAll() 描述中,但不出现在fetch() 描述中。
所以我认为与多行操作相关的常量,例如PDO::FETCH_GROUP,仅用于fetchAll(),而被fetch() 和setFetchMode() 忽略。
如何获取由 ID 索引的数组
我尝试了几种组合,看起来 FETCH_GROUP + FETCH_UNIQUE 可以。
代码
$sql = "SELECT * FROM service_table";
$q = $db->query($sql);
$result = $q->fetchAll(PDO::FETCH_GROUP | PDO::FETCH_UNIQUE | PDO::FETCH_ASSOC);
var_dump($result);
结果
array(2) {
[1] => array(1) {
'name' => string(3) "one"
}
[2] => array(1) {
'name' => string(3) "two"
}
}
另一种选择是使用 FETCH_FUNC 和自定义函数来格式化数据,请参阅 fetchAll() 文档。