我仍然不明白为什么 FETCH_KEY_PAIR 没有在此处记录 (https://php.net/manual/fr/pdo.constants.php),因为它可能非常有用!
<?php
var_dump($pdo->query('select id, name from table')->fetchAll(PDO::FETCH_KEY_PAIR));
?>
这将显示
数组(2) {
[2]=>
字符串(10) "name2"
[5]=>
字符串(10) "name5"
}
(PHP 5 >= 5.1.0, PHP 7, PHP 8, PECL pdo >= 0.1.0)
PDOStatement::fetchAll — 获取结果集中的剩余行
mode
控制返回数组的内容,如 PDOStatement::fetch() 中所述。默认为 PDO::ATTR_DEFAULT_FETCH_MODE
的值(默认为 PDO::FETCH_BOTH
)
要返回一个包含结果集中单个列的所有值的数组,请指定 PDO::FETCH_COLUMN
。可以使用 column
参数指定要获取的列。
要通过特定列的值(而不是连续数字)索引结果数组,请在 SQL 中的列列表中将此列的名称放在第一位,并使用 PDO::FETCH_UNIQUE
。此列必须仅包含唯一值,否则某些数据将丢失。
要以由指定列的值索引的三维数组的形式对结果进行分组,请在 SQL 中的列列表中将此列的名称放在第一位,并使用 PDO::FETCH_GROUP
。
要以二维数组的形式对结果进行分组,请将 PDO::FETCH_GROUP
与 PDO::FETCH_COLUMN
进行按位或运算。结果将按第一列分组,数组元素的值将是第二列中对应条目的列表数组。
column
与 PDO::FETCH_COLUMN
一起使用。返回指定的第 0 个索引列。
class
与 PDO::FETCH_CLASS
一起使用。返回指定类的实例,将每行的列映射到类中的命名属性。
constructorArgs
当 mode
参数为 PDO::FETCH_CLASS
时,自定义类构造函数的参数。
callback
与 PDO::FETCH_FUNC
一起使用。返回调用指定函数的结果,在调用中使用每行的列作为参数。
PDOStatement::fetchAll() 返回一个包含结果集中所有剩余行的数组。该数组将每一行表示为列值的数组或具有对应于每个列名称的属性的对象。如果要获取的结果为零,则返回空数组。
使用此方法获取大型结果集将导致对系统和可能网络资源的大量需求。与其检索所有数据并在 PHP 中操作它,不如考虑使用数据库服务器来操作结果集。例如,在 SQL 中使用 WHERE 和 ORDER BY 子句来限制结果,然后再使用 PHP 检索和处理它们。
如果属性 PDO::ATTR_ERRMODE
设置为 PDO::ERRMODE_WARNING
,则发出级别为 E_WARNING
的错误。
如果属性 PDO::ATTR_ERRMODE
设置为 PDO::ERRMODE_EXCEPTION
,则抛出 PDOException。
示例 #1 获取结果集中的所有剩余行
<?php
$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();
/* 获取结果集中的所有剩余行 */
print "获取结果集中的所有剩余行:\n";
$result = $sth->fetchAll();
print_r($result);
?>
以上示例将输出类似以下内容
Fetch all of the remaining rows in the result set: Array ( [0] => Array ( [name] => apple [0] => apple [colour] => red [1] => red ) [1] => Array ( [name] => pear [0] => pear [colour] => green [1] => green ) [2] => Array ( [name] => watermelon [0] => watermelon [colour] => pink [1] => pink ) )
示例 #2 获取结果集中单个列的所有值
以下示例演示了如何返回结果集中单个列的所有值,即使 SQL 语句本身可能每行返回多列。
<?php
$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();
/* 获取第一列的所有值 */
$result = $sth->fetchAll(PDO::FETCH_COLUMN, 0);
var_dump($result);
?>
以上示例将输出类似以下内容
Array(3) ( [0] => string(5) => apple [1] => string(4) => pear [2] => string(10) => watermelon )
示例 #3 按单个列对所有值进行分组
以下示例演示了如何返回一个关联数组,该数组按结果集中指定列的值进行分组。该数组包含三个键:值 apple
和 pear
返回为包含两种不同颜色的数组,而 watermelon
返回为仅包含一种颜色的数组。
<?php
$insert = $dbh->prepare("INSERT INTO fruit(name, colour) VALUES (?, ?)");
$insert->execute(array('apple', 'green'));
$insert->execute(array('pear', 'yellow'));
$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();
/* 按第一列分组值 */
var_dump($sth->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_GROUP));
?>
以上示例将输出类似以下内容
array(3) { ["apple"]=> array(2) { [0]=> string(5) "green" [1]=> string(3) "red" } ["pear"]=> array(2) { [0]=> string(5) "green" [1]=> string(6) "yellow" } ["watermelon"]=> array(1) { [0]=> string(5) "pink" } }
示例 #4 为每个结果实例化一个类
以下示例演示了PDO::FETCH_CLASS
获取样式的行为。
<?php
class fruit {
public $name;
public $colour;
}
$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();
$result = $sth->fetchAll(PDO::FETCH_CLASS, "fruit");
var_dump($result);
?>
以上示例将输出类似以下内容
array(3) { [0]=> object(fruit)#1 (2) { ["name"]=> string(5) "apple" ["colour"]=> string(5) "green" } [1]=> object(fruit)#2 (2) { ["name"]=> string(4) "pear" ["colour"]=> string(6) "yellow" } [2]=> object(fruit)#3 (2) { ["name"]=> string(10) "watermelon" ["colour"]=> string(4) "pink" } [3]=> object(fruit)#4 (2) { ["name"]=> string(5) "apple" ["colour"]=> string(3) "red" } [4]=> object(fruit)#5 (2) { ["name"]=> string(4) "pear" ["colour"]=> string(5) "green" } }
示例 #5 为每个结果调用函数
以下示例演示了PDO::FETCH_FUNC
获取样式的行为。
<?php
function fruit($name, $colour) {
return "{$name}: {$colour}";
}
$sth = $dbh->prepare("SELECT name, colour FROM fruit");
$sth->execute();
$result = $sth->fetchAll(PDO::FETCH_FUNC, "fruit");
var_dump($result);
?>
以上示例将输出类似以下内容
array(3) { [0]=> string(12) "apple: green" [1]=> string(12) "pear: yellow" [2]=> string(16) "watermelon: pink" [3]=> string(10) "apple: red" [4]=> string(11) "pear: green" }
我仍然不明白为什么 FETCH_KEY_PAIR 没有在此处记录 (https://php.net/manual/fr/pdo.constants.php),因为它可能非常有用!
<?php
var_dump($pdo->query('select id, name from table')->fetchAll(PDO::FETCH_KEY_PAIR));
?>
这将显示
数组(2) {
[2]=>
字符串(10) "name2"
[5]=>
字符串(10) "name5"
}
使 foreach 与 PDO FetchAll() 中的一些数据完美配合
我之前没有正确理解如何使用 foreach 中的 $value 部分,我希望这能帮助其他人。
示例
<?php
$stmt = $this->db->prepare('SELECT title, FMarticle_id FROM articles WHERE domain_name =:domain_name');
$stmt->bindValue(':domain_name', $domain);
$stmt->execute();
$article_list = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
它给出了
数组 (大小=2)
0 =>
数组 (大小=2)
'title' => 字符串 'About Cats Really Long title for the article' (长度=44)
'FMarticle_id' => 字符串 '7CAEBB15-6784-3A41-909A-1B6D12667499' (长度=36)
1 =>
数组 (大小=2)
'title' => 字符串 'another cat story' (长度=17)
'FMarticle_id' => 字符串 '0BB86A06-2A79-3145-8A02-ECF6EA5C405C' (长度=36)
然后使用
<?php
foreach ($article_list as $row => $link) {
echo '<a href="'. $link['FMarticle_id'].'">' . $link['title']. '</a></br>';
}
?>
有趣的是,当您使用 fetchAll 时,对象的构造函数是在分配属性之后调用的。例如
<?php
class person {
public $name;
function __construct() {
$this->name = $this->name . " is my name.";
}
}
# 在此处使用 PDO 设置数据库选择
$obj = $STH->fetchALL(PDO::FETCH_CLASS, 'person');
?>
将导致 ' is my name' 附加到所有名称列。但是,如果您以稍微不同的方式调用它
<?php
$obj = $obj = $STH->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'person');
?>
那么构造函数将在分配属性之前被调用。我找不到任何地方记录这一点,所以我想在这里添加一个注释会很好。
请注意:如果您执行外部左连接并将 PDO FetchALL 设置为 PDO::FETCH_ASSOC,则在连接中没有返回任何记录的情况下,您在外部左连接中使用的任何主键都将设置为空白。
例如
<?php
// 查询产品表并连接到图像表,并返回每个产品的任何图像(如果有)
$sql = "SELECT * FROM product, image
LEFT OUTER JOIN image ON (product.product_id = image.product_id)";
$array = $stmt->fetchAll(PDO::FETCH_ASSOC);
print_r($array);
?>
结果数组将如下所示
数组
(
[0] => 数组
(
[product_id] =>
[notes] => "this product..."
[brand] => "Best Yet"
...
解决方法是简单地在 SELECT 子句中指定字段名称,而不是使用 * 作为通配符,或者,您也可以除了 * 之外还指定字段。以下示例正确返回 product_id 字段
<?php
$sql = "SELECT *, product.product_id FROM product, image
LEFT OUTER JOIN image ON (product.product_id = image.product_id)";
$array = $stmt->fetchAll(PDO::FETCH_ASSOC);
print_r($array);
?>
结果数组将如下所示
数组
(
[0] => 数组
(
[product_id] => 3
[notes] => "this product..."
[brand] => "Best Yet"
...
请注意,对于大型数据集,fetchAll() 可能会极大地降低内存效率。我的内存限制设置为 160 MB,当我尝试以下操作时发生了这种情况
<?php
$arr = $stmt->fetchAll();
// 致命错误:已用内存大小 16777216 字节耗尽
?>
如果您要遍历 fetchAll() 的输出数组,请改用 fetch() 来最大程度地减少内存使用,如下所示
<?php
while ($arr = $stmt->fetch()) {
echo round(memory_get_usage() / (1024*1024),3) .' MB<br />';
// do_other_stuff();
}
// 同一个查询的最后一行仅显示 28.973 MB 的使用量
?>
如果您想使用 PDO::FETCH_CLASS 但不喜欢所有值都是字符串类型,您可以始终使用指定类的 __construct 函数将其转换为其他类型。
另一种方法是使用 mysqlnd,但似乎我需要为此重新编译 PHP。
<?php
class Cdr {
public $a; // int
public $b; // float
public $c; // string
public function __construct() {
$this->a = intval($this->a);
$this->b = floatval($this->b);
}
}
// ...
$arrCdrs = $objSqlStatement->fetchAll(PDO::FETCH_CLASS, 'Cdr');
?>
文档中缺少一些内容。
例如,如果您尝试获取 fetchAll(PDO::CLASS, "Class"),它有时会返回一个包含 NULL 值的对象数组,但获取的对象数量与表行对应。
这样可以正常工作
fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, "Class");
例如
$stm = $pdo->prepare("SELECT * FROM Fruit");
$stm->execute();
$stm->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, "Fruit");
使用 PDO::FETCH_COLUMN 与 PDO::FETCH_GROUP 时要小心。默认情况下,结果按第一列(索引 0)分组,并返回第二列(索引 1)。但是,如果您提供 fetch 参数,它不会影响返回的列,而是影响分组列。如果显式设置了分组列,则返回第一列而不是第二列。
<?php
$insert = $dbh->prepare("INSERT INTO people(id, gender) VALUES (?, ?)");
$insert->execute(array('2', 'female'));
$insert->execute(array('3', 'female'));
$insert->execute(array('4', 'female'));
$insert->execute(array('5', 'male'));
$insert->execute(array('6', 'male'));
$sth = $dbh->prepare("SELECT gender, id FROM people");
$sth->execute();
/* 按第一列分组 */
var_dump($sth->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_GROUP));
?>
返回值
<?php
array (size=2)
'female' =>
array (size=3)
0 => string '2' (length=1)
1 => string '3' (length=1)
2 => string '4' (length=1)
'male' =>
array (size=2)
0 => string '5' (length=1)
1 => string '6' (length=1)
?>
但是,
<?php
var_dump($sth->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_GROUP, 0));
?>
返回值
<?php
array (size=2)
'female' =>
array (size=3)
0 => string 'female' (length=1)
1 => string 'female' (length=1)
2 => string 'female' (length=1)
'male' =>
array (size=2)
0 => string 'male' (length=1)
1 => string 'male' (length=1)
?>
和
<?php
var_dump($sth->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_GROUP, 1));
?>
返回值
<?php
数组 (大小=5)
2 =>
数组 (大小=1)
0 => 字符串 'female' (长度=1)
3 =>
数组 (大小=1)
0 => 字符串 'female' (长度=1)
4 =>
数组 (大小=1)
0 => 字符串 'female' (长度=1)
5 =>
数组 (大小=1)
0 => 字符串 'male' (长度=1)
6 =>
数组 (大小=1)
0 => 字符串 'male' (长度=1)
?>
第一列被返回,并且根据提供的列索引进行分组。
如果您使用 PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE 标记将列映射到对象属性,则 fetchAll() 在执行映射时将使用对象具有的任何 __set() 方法。
请注意,您只能在选择两列时使用 PDO::FETCH_COLUMN|PDO::FETCH_GROUP 对,而不是像 DB_common::getAssoc() 那样,当分组设置为 true 时。
Oracle 和 MSSQL 还支持另一种获取模式
PDO::FETCH_ASSOC
> 只获取列名并省略数字索引。
如果您希望使用列键作为表标题从 SQL 语句中返回所有列,则只需执行以下操作即可
<?php
$dbh = new PDO("DS", "USERNAME", "PASSWORD");
$stmt = $dbh->prepare("SELECT * FROM tablename");
$stmt->execute();
$arrValues = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 打开表格
print "<table wdith=\"100%\">\n";
print "<tr>\n";
// 添加表头
foreach ($arrValues[0] as $key => $useless){
print "<th>$key</th>";
}
print "</tr>";
// 显示数据
foreach ($arrValues as $row){
print "<tr>";
foreach ($row as $key => $val){
print "<td>$val</td>";
}
print "</tr>\n";
}
// 关闭表格
print "</table>\n";
?>
PHP 从 SQL Server 2005 中获取所有数据
如果字段的数据类型为 varchar(nvarchar),则仅获取 255 个字符。但“text”数据类型是可以的。
因此,请注意!将 'varchar' 或 'nvarchar'(长度 > 255)更改为 'text' 数据类型。
希望对您有所帮助。
<?php
$user = 'sa';
$pass = 'pass';
$conn = new PDO('mssql:host=127.0.0.1; dbname=tempdb;', $user, $pass);
$mainSQL = "SELECT field_varchar, field_text FROM table1";
$sth = $conn->prepare($mainSQL);
$sth->setFetchMode(PDO::FETCH_ASSOC);
$sth->execute();
$retRows = $sth->fetchAll();
// field_varchar 字段仅获取 255 个字符(最大)
// field_text 字段是可以的。
var_dump($retRows);
unset($sth); unset($conn);
?>
可能有些用户需要将其 MySQL 类升级到 PDO 类。获取结果的方式已从 while 循环更改为 foreach 循环。对于希望在 while 循环中获取结果的用户,这里有一个简单的技巧。
<?php
$db = new DB();
$query = $db->prepare("SELECT * FROM CPUCategory");
$query = $db->execute();
$result = $db->fetchAll();
var_dump($result);
?>
输出将是
数组(2) {
[0]=> 数组(2) {
["ccatid"]=> 整数(1)
["ccatname"]=> 字符串(5) "Intel"
}
[1]=> 数组(2) {
["ccatid"]=> 整数(2)
["ccatname"]=> 字符串(3) "AMD"
}
}
看起来不像旧函数的输出。
[原始样式] mysql_fetch_array($query)
[MYSQL 类] $db->fetch_array($query)
您可能会放弃。
但有一种简单的方法可以使用 while 循环来获取结果。
<?php
$db = new DB();
$query = $db->prepare("SELECT * FROM CPUCategory");
$query = $db->execute();
$result = $db->fetchAll();
$row = array_shift($result);
// 如果您现在需要获取它们,请将其放入 while 循环中,如下所示:
// while($row = array_shift($result)) { ... }
var_dump($row);
?>
输出将以单个数组显示,while 循环返回 TRUE
数组(2) {
["ccatid"]=> 整数(1)
["ccatname"]=> 字符串(5) "Intel"
}
因此,在获取此行后,while 循环再次运行并获取下一行,直到所有行都已获取,然后 while 循环将返回 false。(就像旧函数所做的那样)
当您需要升级到 PDO 类时,不需要修改太多代码,请记住。
错误
SQLSTATE[HY000]: 一般错误:2014 在其他未缓冲的查询处于活动状态时无法执行查询。请考虑使用 PDOStatement::fetchAll()。或者,如果您的代码仅在 mysql 上运行,则可以通过设置 PDO::MYSQL_ATTR_USE_BUFFERED_QUERY 属性来启用查询缓冲。
如果您正在使用类似以下内容
while ($row = $query->fetchObject()) {
[...]
}
尝试改用以下内容
$rows = $query->fetchAll(PDO::FETCH_CLASS, 'ArrayObject');
foreach ($rows as $row) {
[...]
}
我在这里添加它,因为我似乎找不到任何清晰易懂的 PDO::FETCH_GROUP 示例和解释以及它是如何工作的。
我发现这是 fetchAll() 中最有用的一种模式之一,当您需要处理任何形式的分组时。
从本质上讲,PDO 可以根据选定的第一个字段将结果分组到嵌套数组中。
示例
<?php
$data = $pdo->query('SELECT sex, name, car FROM users')->fetchAll(PDO::FETCH_GROUP);
/* 数组 (
'male' => 数组 ( 0 =>
数组 (
'name' => 'John',
'car' => 'Toyota',
),
1 => 数组 (
'name' => 'Mike',
'car' => 'Ford',
),
),
'female' => 数组 (
0 => 数组 (
'name' => 'Mary',
'car' => 'Mazda',
),
1 => 数组 (
'name' => 'Kathy',
'car' => 'Mazda',
),
),
) */
?>
提示:如果您需要按第一个字段以外的其他内容对数据进行分组,则也可以按如下方式执行
<?php
SELECT sex, users.* FROM users
?>
我注意到一个相当奇怪(至少对我来说)的行为。也许它可以帮助遇到同样问题的人。
<?php
$stmt = new PDOStatement();
$foo = $stmt->fetchAll();
var_dump($foo);
$stmt = $pdo->prepare('SELECT VERSION()');
$foo = $stmt->fetchAll();
var_dump($foo);
$stmt = $pdo->prepare("INSERT INTO `tblnm` (date) VALUES (NOW())");
$stmt->execute();
$foo = $stmt->fetchAll();
var_dump($foo);
$stmt = $pdo->query("INSERT INTO `tblnm` (date) VALUES (NOW())");
$foo = $stmt->fetchAll();
var_dump($foo);
?>
第一个只是一个空对象,所以 $foo === bool(false)
第二个没有执行,所以 $foo === array(0) {}
第三个和第四个在 fetchAll() 处抛出异常
"General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, [...] you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute."
fetchAll() 已经被使用了,并且在 true 和 false 之间切换上述属性没有任何改变。
这可能是由于 INSERT 没有返回值引起的。我们可以在 SQL 中使用 RETURNING,但它比较新,所以可能还没有在所有地方都得到支持。
最终对我来说有效的解决方案是 $pdo->exec() 和 lastInsertId(),因为无论如何 ID 是我唯一需要的列。
<?php
$count = $pdo->exec('INSERT INTO `tblnm` (date) VALUES (NOW())');
$foo = $pdo->lastInsertId();
var_dump($foo);
?>
然后例如 $foo === string(2) "93"
从 PHP<7.4 升级到 PHP 8.0 会有重大更改。如果您的类扩展了 PDOStatement,则 PHP 8.0 的类型原型不兼容
- PHP 7.4 = public PDOStatement::fetchAll ([ int $fetch_style [, mixed $fetch_argument [, array $ctor_args = array() ]]] ) : array
- PHP 8.0 = public PDOStatement::fetchAll ([ int $mode = PDO::FETCH_BOTH[, mixed ...$args] ]) : array
虽然对于人类来说它们是兼容的,但 PHP 并不喜欢它
- PHP 7.4 = PHP Warning: Declaration of (your class prototype) should be compatible with (PDOStatement's prototype)
- PHP 8.0 = [PhpCompileError] Declaration of (your class prototype) must be comptable with (PDOStatement's prototype)
因为第一个是警告,它不是致命的,您可能很乐意使用 PHP 8.0 的原型。我个人的解决方案是停止扩展 PDOStatement,从而重写相关的类型声明和条件。
带有返回值对象的方法 (PHP 7.2)
类 MySql {
public function __construct()
{
parent::__construct();
尝试 {
$options = array
(
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES UTF8"
);
$this->pdo = new PDO('mysql:host=127.0.0.1;dbname=testuser','dbtest', 'xxxxxxx',$options);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
}
public function selectAll(string $sql)
{
$conn = $this->pdo->query($sql);
return $conn->fetchAll(PDO::FETCH_OBJ);
}
}
我惊奇地发现你实际上可以组合 PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE | PDO::FETCH_UNIQUE,因为 PDO::FETCH_CLASSTYPE 和 PDO::FETCH_UNIQUE 都说它们将使用第一列,但事实证明 PDO::FETCH_CLASSTYPE 优先,然后 PDO::FETCH_UNIQUE 将使用下一列。这样你就可以创建一个对象的关联数组,其中表的一列作为键。例如,查询如
'SELECT Class, Id, t.* FROM subscriptions_tbl t'
可能会给你这个结果
数组
(
[20481086] => WConsumerSubscription 对象
(
[Variant] => 2
[_Expiration:WSubscriptionModel:private] => DateTime 对象
(
[date] => 2018-08-08 00:00:00.000000
[timezone_type] => 3
[timezone] => UTC
)
[Notes] =>
[Id] => 20481086
[_Deleted:protected] => 0
[_VersionNo:protected] => 2
[ContactId] =>
[ConsumerId] => 2
)
[21878324] => WAdminSubscription 对象
(
[Variant] =>
[_Expiration:WSubscriptionModel:private] =>
[Notes] =>
[Id] => 21878324
[_Deleted:protected] => 0
[_VersionNo:protected] => 1
[ContactId] =>
)
)
将参数直接注入 `fetchAll` 而不是使用 `bindValue`
$query = "
SELECT
a.total_paid_tax_incl AS prize,
a.date_add AS date_add
FROM orders a
WHERE a.order_id = :seventeen
AND a.name = :name";
// 连接 (例如在 Symfony 中,您使用命名空间 Doctrine\DBAL\Connection 中的 Connection 类)
$this->connection->fetchAll($query, ['seventeen' => 70, 'name' => 'Sidi'])
如果要将行作为未定义类的对象获取,可以执行以下操作
<?php
$result = $q->fetchAll(PDO::FETCH_OBJ);
?>
当将 PDO::FETCH_CLASS 作为第一个参数传递时,此方法将接受类名作为第二个选项
<?php
$query = $pdo->prepare($sql);
$result = $query->execute($values);
if ($result && $query->rowCount() > 0) {
$records = $query->fetchAll(PDO::FETCH_CLASS, 'Some_Class');
// $record 现在是 Some_Class 对象的数组
}
?>
- Davey
由于这些查询的结果结构(包含结果的查询数组中的数组),我在将 PDO 查询结果返回到数组时遇到了麻烦。现在,当对查询执行 fetchAll() 时,您将获得以下内容
数组 ( [0] = 数组 ( [key1] => "value1", [key2] => "value2") [1] = 数组( [key1] => "value1", [key2] => "value2") )
这是一个较小的数组,但以这种方式在 HUGE 数据库中返回结果,并且很快就会变得无法读取给定的数组。
这就是辉煌的 foreach 派上用场的地方!我们都知道 foreach 的基本写法 (foreach ($array as $key => $value) {...}),但在查询结果中有一个变化,因为 $key 和 $value 变量都是数组,其中 $key 是包含结果数组的查询数组,而 $value 是结果数组本身。
所以在这个 foreach 中,我们必须直接与 $value 交谈以获取我们的结果!这看起来像这样
<?php
foreach ($query as $key => $value) {
return $value["key2"];
}
?>
这已经完成了工作,但要以数组形式返回它们,我们必须稍微更改一下 return 代码,如下所示
<?php
foreach ($query as $key => $value) {
return array (
"key1" => $value["key1"],
"key2" => $value["key2"]
);
}
?>
此 foreach 循环遍历查询数组,就像第一个一样,但 return 代码只是不返回表示结果数组的键 ($key),而只返回存储在 $value 中的结果数组内部的键。这给了我们一个如下所示的数组
数组 ( [key1] => "value1", [key2] => "value2")
如果正确编写,这应该返回数组中的所有值。我仍然存在 foreach 未返回所有结果的问题,但这篇笔记主要是为了展示它如何以数组形式返回。
如果您尝试调用 PDOStatement::fetchAll 并且没有按预期获取结果集(而是空),请检查是否首先调用了 PDOStatement::execute。
请记住,PDOStatement::fetchAll 不会执行查询,它只是挂载数组。
:)