PHP中使用PDO查询时如何在无结果时跳过foreach循环
我来帮你解决这个问题!核心问题在于你误解了$stmt的类型——它是PDOStatement对象,不是普通数组,所以你之前用empty()、is_array()的判断逻辑全错了,这就是为什么你的提示消息要么不显示、要么总是显示的原因。
正确的处理方式
我们可以先把查询结果转换成数组,再判断是否为空,这样逻辑就清晰了:
// 你的预处理查询不变 $stmt = $conn->prepare('SELECT a.`zone`, b.`source_customer_billing_zone_id`, b.`source_external_subscriber_id`, SUM((CEIL(b.`duration`))/60) AS minutos, SUM((b.`source_customer_cost`)/100) AS total FROM `billing`.billing_zones a INNER JOIN cdr b ON a.`id` = b.`source_customer_billing_zone_id` WHERE source_external_subscriber_id = :source_external_subscriber_id GROUP BY b.`source_external_subscriber_id`, a.`zone` ORDER BY total desc'); $stmt->execute(array('source_external_subscriber_id' => $source_external_subscriber_id)); // 把查询结果转换成关联数组 $results = $stmt->fetchAll(PDO::FETCH_ASSOC); if (!empty($results)) { // 有数据时循环处理 foreach ($results as $row) { $newData = [ 'name' => $row['zone'], 'sku' => $row['source_customer_billing_zone_id'], 'units' => $row['minutos'], 'subtotal' => $row['total'], 'tax' => 21, 'account' => $account ]; array_push($invoice['products'], $newData); } } else { // 无数据时执行提示或跳过逻辑 $msg = "There are no entries for this customer ID"; var_dump($msg); // 如果需要跳过后续处理,可以加 continue; 或者其他逻辑 }
为什么之前的方法失效?
我给你拆解下之前的问题:
- 第一种方案:如果查询无结果,
foreach ($stmt as $row)根本不会进入循环,所以else分支永远不会触发。 - 第二种方案:
$stmt是PDOStatement对象,永远不会为空,所以else分支永远不会执行。 - 第三种方案:
$stmt确实不是数组,所以不管有没有结果,都会进入if (!is_array($stmt))分支,导致提示总是显示。
可选优化(适合大数据量)
如果你的查询结果可能很大,不想一次性加载到内存里,可以用fetch()循环判断:
$stmt->execute(array('source_external_subscriber_id' => $source_external_subscriber_id)); // 先获取第一行结果 $row = $stmt->fetch(PDO::FETCH_ASSOC); if ($row) { // 有数据时循环处理所有行 do { $newData = [ 'name' => $row['zone'], 'sku' => $row['source_customer_billing_zone_id'], 'units' => $row['minutos'], 'subtotal' => $row['total'], 'tax' => 21, 'account' => $account ]; array_push($invoice['products'], $newData); } while ($row = $stmt->fetch(PDO::FETCH_ASSOC)); } else { $msg = "There are no entries for this customer ID"; var_dump($msg); }
这样每次只加载一行数据,不会占用太多内存,适合处理大量数据的场景。
内容的提问来源于stack exchange,提问作者Berny
相关产品推荐
相关产品推荐

