PHP:使用fetch_array的While循环陷入无限执行?
问题原因分析
你遇到的死循环问题其实很典型——你的fetch_array函数每次被调用时都会重新执行完整的SQL查询,而不是遍历已有的结果集。
看一下你的代码逻辑:
while($news = $engine->fetch_array("SELECT * FROM `cms_news` ORDER BY `id` DESC")) { echo 'lol<br>'; }
每次循环判断条件时,都会调用fetch_array,这个函数内部会重新执行SELECT * FROM cms_news...语句,然后返回结果集的第一条记录。所以每次循环都能拿到有效数据,永远不会返回false,循环自然就会一直跑下去直到触发超时。
而你的fetch_array实现也确实是这样:
final public function fetch_array($sql) { $result = $this->connection->query($sql); return $result->fetch_array(MYSQLI_ASSOC); }
它没有保存结果集的状态,每次调用都重新发起查询,完全没办法实现“遍历所有记录”的需求。
修复方案
我们需要把执行查询和遍历结果集拆成两步:先执行一次SQL拿到完整的结果集,再循环遍历这个结果集里的每一行。这里有两种常见的修复方式:
方式1:修改fetch_array函数,支持结果集复用(推荐)
给fetch_array加一个可选参数,让它既能接受SQL语句,也能接受已有的结果集:
final public function fetch_array($input) { // 如果传入的是SQL字符串,先执行查询并保存结果集 if(is_string($input)){ $result = $this->connection->query($input); $this->current_result = $result; // 把结果集存在类属性里,方便后续复用 } else { $result = $input; // 如果传入的是结果集,直接使用 } return $result->fetch_array(MYSQLI_ASSOC); }
然后调用的时候,先执行一次查询拿到结果集,再循环遍历:
// 先执行一次查询,拿到结果集 $result = $engine->connection->query("SELECT * FROM `cms_news` ORDER BY `id` DESC"); // 循环遍历结果集的每一行 while($news = $engine->fetch_array($result)) { echo 'lol<br>'; }
方式2:直接调整调用逻辑,不修改类函数
如果不想改动$engine类的代码,可以跳过封装函数,直接操作结果集:
// 先执行查询拿到完整结果集 $result = $engine->connection->query("SELECT * FROM `cms_news` ORDER BY `id` DESC"); // 直接遍历结果集的每一行 while($news = $result->fetch_array(MYSQLI_ASSOC)) { echo 'lol<br>'; }
这样就能正确遍历数据库里的3条记录,不会再出现死循环超时的问题了。
内容的提问来源于stack exchange,提问作者user5405648
相关产品推荐
相关产品推荐

