php PDO fetchAll () – пока не работает, foreach works

Я хотел бы знать, если я делаю все правильно, или 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»?

Fetch 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 } 

Слово предупреждения, хотя: получить все будет делать именно это, если размер результата большой, он будет подчеркивать ресурсы на вашем компьютере. Я бы сделал это только в том случае, если я знаю, что набор результатов будет небольшим, или я заставляю это применять ограничение к запросу.

Из руководства PHP:

Значение утверждения while просто. Он сообщает PHP, чтобы выполнять вложенные инструкции (ы) несколько раз, пока выражение while оценивает значение TRUE.

Поскольку метод, который вы используете, возвращает массив, while ($row=$page->fetchAll(PDO::FETCH_ASSOC)) устанавливает $ row в массив всего набора результатов. То, что вы ожидаете, – это метод fetchAll для расширения класса Iterator , чего нет.

foreach – это правильный путь.

нет необходимости перебирать набор записей, потому что fetchAll – хорошо извлекает все записи в одной команде. Приятно, не так ли?

 $rows = $page->fetchAll(PDO::FETCH_ASSOC); // $rows is an array containing all records... foreach ($rows as $row) echo $row->fieldname; 

Я попытался воспроизвести ваше дело. Смотри сюда:

script.php

 <?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 интерпретирует его как истинный и работает один раз.

Пока foreach будет перебирать массив массивов, и каждый раз вы будете иметь соответствующую строку.

С fetchAll In while вы fetchAll все записи на первой итерации, и в следующий раз ничего не получится. В foreach также вы извлекали все записи в первой строке, но foreach использует результат для итерации.