PHP中能否重新开启已关闭的while循环复用数据库查询结果?
解决办法
问题出在PDO的结果集遍历机制上:$posts->fetch()是单向读取的,第一次while循环会把结果集里的所有数据都取完,指针移动到结果集末尾,第二次循环时fetch()直接返回false,所以循环不会执行。
下面是两种可靠的解决方式:
方式一:提前把所有数据存入数组(推荐)
先一次性把所有帖子数据读取到数组中,之后多次遍历这个数组即可,这种方法兼容性最好,逻辑也简单。
步骤1:预取所有数据
在HTML代码之前,先执行这段代码把数据存入数组:
<?php // 初始化空数组存储所有帖子数据 $allPosts = []; while($data = $posts->fetch(PDO::FETCH_ASSOC)) { $allPosts[] = $data; } // 关闭游标释放数据库连接资源 $posts->closeCursor(); ?>
步骤2:第一个小部件遍历数组
<!-- First part of HTML Code... --> <?php foreach($allPosts as $data): ?> <tr class="row posts"> <th scope="row"><?=htmlspecialchars($data['id'])?></th> <td><?=htmlspecialchars($data['title'])?></td> <td><?=htmlspecialchars($data['creation_date_fr'])?></td> <td><a href="index.php?action=editPost&id=<?=$data['id']?>">Éditer l'article</a></td> <td><a href="index.php?action=deletePost&id=<?=$data['id']?>" class="deletePost"><ion-icon name="trash"></ion-icon></a></td> </tr> <?php endforeach; ?> <!-- Another part of HTML code... -->
步骤3:第二个小部件遍历数组
<!-- then --> <?php foreach($allPosts as $data): ?> <!-- 这里放第二个小部件的展示代码,示例如下 --> <div class="post-widget"> <p><?=htmlspecialchars($data['title'])?> - <?=htmlspecialchars($data['creation_date_fr'])?></p> </div> <?php endforeach; ?>
方式二:使用可滚动结果集重置指针
如果不想提前把数据存入数组,可以在执行查询时设置可滚动游标,之后通过重置指针来重新遍历结果集。注意:部分数据库驱动可能不支持该特性,MySQL是支持的。
步骤1:执行查询时设置可滚动游标
// 执行查询时指定CURSOR_SCROLL参数,创建可滚动结果集 $posts = $pdo->query('SELECT * FROM posts', PDO::FETCH_ASSOC, PDO::CURSOR_SCROLL);
步骤2:两次循环之间重置指针
<!-- First part of HTML Code... --> <?php while($data = $posts->fetch(PDO::FETCH_ASSOC)): ?> <tr class="row posts"> <th scope="row"><?=htmlspecialchars($data['id'])?></th> <td><?=htmlspecialchars($data['title'])?></td> <td><?=htmlspecialchars($data['creation_date_fr'])?></td> <td><a href="index.php?action=editPost&id=<?=$data['id']?>">Éditer l'article</a></td> <td><a href="index.php?action=deletePost&id=<?=$data['id']?>" class="deletePost"><ion-icon name="trash"></ion-icon></a></td> </tr> <?php endwhile; ?> <!-- Another part of HTML code... --> <!-- then --> <?php // 重置结果集指针到开头 $posts->rewind(); ?> <?php while($data = $posts->fetch(PDO::FETCH_ASSOC)): ?> <!-- 第二个小部件的展示代码 --> <div class="another-widget"> <span>ID: <?=htmlspecialchars($data['id'])?></span> </div> <?php endwhile; ?> <?php $posts->closeCursor(); ?>
内容的提问来源于stack exchange,提问作者wlvlm
相关产品推荐
相关产品推荐

