我有一个关于PDO的问题。
两者之间有区别吗
$sql = "SELECT * FROM pages";
$pdo = $this->db->query($sql);
$result = $pdo->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_ASSOC);
和
$sql = "SELECT * FROM pages";
$pdo = $this->db->query($sql);
$pdo->setFetchMode(PDO::FETCH_GROUP|PDO::FETCH_ASSOC);
$result = $pdo->fetchAll();
?
我为他们每个人得到不同的$result
。
PHP 中关于这些获取模式的文档对我来说不是很清楚。
我有一个包含不同页面的表,我想获取按其 ID 索引的所有页面。
第一种方法返回以下内容:
[
[id of page 1] => [
[0] => [ page 1 ],
],
[id of page 2] => [
[0] => [ page 2 ],
],
...
]
当我做第二种方法时,我只得到:
[
[0] => [ page 1 ],
[1] => [ page 2 ],
[3] => [ page 3 ],
...
]
我想要这样:
[
[id of page 1] => [ page 1 ],
[id of page 2] => [ page 2 ],
[id of page 3] => [ page 3 ],
...
]
第一个对我来说已经足够了,因为我可以使用数组映射函数轻松调整它:
array_map('reset', $result);
解释似乎是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 常量的列表。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()
文档。