You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PDO查询大量数据避内存耗尽:视图用fetch()不混逻辑的方案

解决方案

方案1:将PDO结果集包装为迭代器传入视图

PDO的Statement对象本身实现了可遍历接口,直接返回该对象给视图,视图通过foreach遍历即可自动触发逐行fetch(),既避免一次性加载所有数据占满内存,又严格遵循MVC分离规则——模型负责查询逻辑,视图仅做渲染。

模型层(functions.php)

function get_table_rows() {
    $pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
    $stmt = $pdo->query('SELECT * FROM large_table');
    // 返回Statement对象而非fetchAll()的数组
    return $stmt;
}

控制器层(示例:index.php)

// 调用模型获取结果集
$stmt = get_table_rows();
// 将结果集传入视图
include 'html.php';

视图层(html.php)

<table>
    <thead>
        <tr><th>ID</th><th>名称</th></tr>
    </thead>
    <tbody>
        <!-- 直接遍历Statement对象,底层自动逐行获取数据 -->
        <?php foreach ($stmt as $row): ?>
        <tr>
            <td><?= $row['id'] ?></td>
            <td><?= $row['name'] ?></td>
        </tr>
        <?php endforeach; ?>
    </tbody>
</table>

方案2:控制器循环fetch,视图负责单一行渲染

把逐行获取的逻辑放在控制器,视图仅负责渲染单一行的HTML片段,彻底隔离查询逻辑与视图层。

模型层(functions.php)

function get_table_stmt() {
    $pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
    return $pdo->query('SELECT * FROM large_table');
}

控制器层(示例:index.php)

$stmt = get_table_stmt();
// 加载表格头部视图
include 'table_header.php';
// 控制器内逐行获取数据,调用行视图渲染
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    include 'table_row.php';
}
// 加载表格尾部视图
include 'table_footer.php';

视图片段:table_header.php

<table>
    <thead>
        <tr><th>ID</th><th>名称</th></tr>
    </thead>
    <tbody>

视图片段:table_row.php

<tr>
    <td><?= $row['id'] ?></td>
    <td><?= $row['name'] ?></td>
</tr>
</tbody>
</table>

方案3:用生成器封装逐行获取逻辑

通过PHP生成器在模型层封装逐行fetch()的细节,返回生成器对象给视图,视图遍历生成器即可逐行获取数据,内存仅保留当前行数据,同时视图无需感知底层实现。

模型层(functions.php)

function get_table_rows_generator() {
    $pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
    $stmt = $pdo->query('SELECT * FROM large_table');
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        yield $row;
    }
}

控制器层(示例:index.php)

$rows_generator = get_table_rows_generator();
include 'html.php';

视图层(html.php)

<table>
    <thead>
        <tr><th>ID</th><th>名称</th></tr>
    </thead>
    <tbody>
        <?php foreach ($rows_generator as $row): ?>
        <tr>
            <td><?= $row['id'] ?></td>
            <td><?= $row['name'] ?></td>
        </tr>
        <?php endforeach; ?>
    </tbody>
</table>

内容的提问来源于stack exchange,提问作者itajackass

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 04:07:35