我想知道我是否正常或者fetchAll()不适用于WHILE。
这是一个例子
$db=new PDO("mysql:host=" .$dbhost. "; dbname=" . $dbname, $dbuser, $dbpass);
$page=$db->prepare("SELECT * FROM page");
$page->execute();
foreach ($page->fetchAll(PDO::FETCH_ASSOC) as $row) {
//echo a row
//is working
}
但是,如果尝试使用一段时间循环
while ($row=$page->fetchAll(PDO::FETCH_ASSOC)){
//echo a row
//Show empty
}
我试图只使用fetch(),它正在工作,我的问题:为什么fetchAll()不能用于“WHILE”?
答案 0 :(得分:18)
获取all返回结果集中剩余的所有记录。考虑到这一点,您的foreach能够按预期迭代结果集。
对于等效实现,应使用$page->fetch(PDO::FETCH_ASSOC);
while ($row = $page->fetch(PDO::FETCH_ASSOC)){
// do something awesome with row
}
如果您想使用一段时间并获取所有可以执行的操作
$rows = $page->fetchAll(PDO::FETCH_ASSOC);
// use array_shift to free up the memory associated with the record as we deal with it
while($row = array_shift($rows)){
// do something awesome with row
}
有一句警告:获取所有内容将完全相同,如果结果大小很大,它将会给您的机器上的资源带来压力。我只会知道结果集很小,或者我通过对查询应用限制来强制执行此操作。
答案 1 :(得分:7)
从PHP手册:
while语句的含义很简单。它告诉PHP重复执行嵌套语句,只要while表达式的计算结果为TRUE。
由于the method you're using返回一个数组,
while ($row=$page->fetchAll(PDO::FETCH_ASSOC))
将$ row设置为整个结果集的数组。您期望fetchAll方法扩展Iterator class,而不是{{3}}。
foreach
是正确的方式。
答案 2 :(得分:4)
无需遍历记录集,因为fetchAll
- 很好 - 在一个命令中提取全部记录。很好,不是吗?
$rows = $page->fetchAll(PDO::FETCH_ASSOC);
// $rows is an array containing all records...
foreach ($rows as $row)
echo $row->fieldname;
答案 3 :(得分:2)
我试图重现你的情况。看这里:
<?php
$host = 'localhost';
$user = "user";
$password = '';
$db_name = 'test';
$port = 3306;
try
{
$connection = new PDO("mysql:host=$host;port=$port;dbname=$db_name", $user, $password);
$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e)
{
echo 'Connection failed: ' . $e->getMessage();
}
$page=$connection->prepare("SELECT * FROM Document");
$page->execute();
while ($row = $page->fetchAll(PDO::FETCH_ASSOC)) {
var_dump($row);
}
DROP TABLE IF EXISTS `Document`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `Document` (
`DataID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`Description` varchar(50) CHARACTER SET utf8 NOT NULL,
PRIMARY KEY (`DataID`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `Document`
--
LOCK TABLES `Document` WRITE;
/*!40000 ALTER TABLE `Document` DISABLE KEYS */;
INSERT INTO `Document` VALUES (1,'!!!'),(2,'This is document 2'),(3,'This is document 3'),(4,'This is document 4'),(5,'Hello');
/*!40000 ALTER TABLE `Document` ENABLE KEYS */;
UNLOCK TABLES;
$php script.php
array(5) {
[0]=>
array(2) {
["DataID"]=>
string(1) "1"
["Description"]=>
string(3) "!!!"
}
[1]=>
array(2) {
["DataID"]=>
string(1) "2"
["Description"]=>
string(18) "This is document 2"
}
[2]=>
array(2) {
["DataID"]=>
string(1) "3"
["Description"]=>
string(18) "This is document 3"
}
[3]=>
array(2) {
["DataID"]=>
string(1) "4"
["Description"]=>
string(18) "This is document 4"
}
[4]=>
array(2) {
["DataID"]=>
string(1) "5"
["Description"]=>
string(5) "Hello"
}
}
输出意味着,while语句执行一次并打印出查询应返回的所有行,这绝对是正确的,因为fetchAll返回包含所有行的数组数组。 PHP将其解释为true并运行一次。
虽然foreach
将迭代数组数组,但每次都会有相应的行。
答案 4 :(得分:0)
使用fetchAll
在while循环中,您已经在第一次迭代中获取了所有记录,并且下次没有任何内容可以获取。在foreach
中,您还获取了第一行中的所有记录,但foreach
使用结果进行迭代。