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

基于MVC的MySQL分页查询问题:传递页码与分类ID

问题解决指南:MVC分页+分类查询的常见问题修复

看起来你在MVC架构下实现商品分页和分类查询时遇到了几个典型问题,我来一步步帮你解决:

1. 修复LIMIT查询无数据返回的问题

你的当前代码有两个核心问题导致无数据:

  • SQL参数拼接的风险与类型问题:直接把$arithmetic拼进SQL语句,即使$pn是整数,PDO默认会把它当作字符串处理,可能导致MySQL解析LIMIT参数出错。应该用参数绑定并指定整数类型。
  • 总数量计算错误:你用count($products)获取总商品数,但这只是当前页的商品数量,不是整个分类的总数量,会导致分页逻辑完全错误(比如如果当前页没数据,$total为0,分页页码直接消失)。

修正后的Model函数

// 获取分页商品列表,支持排序
function get_products_by_category($category_id, $pn, $per_page = 8, $sort_by = 'productID', $sort_order = 'ASC') {
    global $db;
    // 白名单验证排序字段,防止SQL注入
    $allowed_sort_fields = ['productID', 'productName', 'price', 'categoryID'];
    $sort_by = in_array($sort_by, $allowed_sort_fields) ? $sort_by : 'productID';
    $sort_order = strtoupper($sort_order) === 'DESC' ? 'DESC' : 'ASC';
    
    $offset = ($pn - 1) * $per_page;
    // 使用参数绑定LIMIT的偏移量和每页数量,指定整数类型
    $query = "SELECT * FROM products 
              WHERE products.categoryID = :category_id 
              ORDER BY $sort_by $sort_order 
              LIMIT :offset, :per_page";
    $statement = $db->prepare($query);
    $statement->bindValue(":category_id", $category_id, PDO::PARAM_INT);
    $statement->bindValue(":offset", $offset, PDO::PARAM_INT);
    $statement->bindValue(":per_page", $per_page, PDO::PARAM_INT);
    $statement->execute();
    $products = $statement->fetchAll();
    $statement->closeCursor();
    return $products;
}

// 获取分类下的总商品数,用于计算分页
function get_total_products_by_category($category_id) {
    global $db;
    $query = "SELECT COUNT(*) FROM products WHERE categoryID = :category_id";
    $statement = $db->prepare($query);
    $statement->bindValue(":category_id", $category_id, PDO::PARAM_INT);
    $statement->execute();
    $total = $statement->fetchColumn();
    $statement->closeCursor();
    return $total;
}

2. 修复分页链接同时传递page_number和category_id的问题

你的分页链接有两个错误:

  • URL参数格式错误:用了&?category_id,正确的参数连接只需要&,不需要重复加?
  • 错误使用循环变量:$category['categoryID']是分类循环结束后的最后一个分类ID,应该用当前选中的分类ID

修正后的Controller代码(关键部分)

// 定义每页数量,避免硬编码
define('PER_PAGE', 8);

if ($action == 'list_products') {
    $category_id = filter_input(INPUT_GET, 'category_id', FILTER_VALIDATE_INT);
    if ($category_id == NULL || $category_id == FALSE) {
        $category_id = 1;
    }
    // 获取总商品数
    $total_products = get_total_products_by_category($category_id);
    // 获取当前页商品
    $products = get_products_by_category($category_id, $pn, PER_PAGE);
    // 计算总页数(用ceil向上取整,避免小数页码)
    $total_page = ceil($total_products / PER_PAGE);
    // 确保页码不超出范围
    if ($pn > $total_page && $total_page > 0) {
        $pn = $total_page;
        $products = get_products_by_category($category_id, $pn, PER_PAGE);
    }
    // 把当前分类ID传递给视图
    $current_category = $category_id;
    include('product_list.php');
}

修正后的视图分页链接

<section>
<?php if ($total_page > 1): ?>
    <?php for($i = 1; $i <= $total_page; $i++) { 
        // 用http_build_query自动拼接参数,避免手动拼接出错
        $params = http_build_query([
            'page_number' => $i,
            'category_id' => $current_category
        ]);
    ?>
    <a href="?<?php echo $params; ?>"><?php echo $i; ?></a>
    &nbsp;
    <?php } ?>
<?php endif; ?>
</section>

3. 避免硬编码与多查询函数的优化

  • 硬编码页面/数量:用define('PER_PAGE', 8)定义每页数量,后续修改只需要改这一处;视图里的分页逻辑通过$total_page动态生成,不需要硬编码页码。
  • 多查询函数问题:给Model函数添加可选的排序参数($sort_by和$sort_order),并通过白名单验证防止SQL注入,这样同一个函数可以支持不同的排序需求,不需要创建多个查询函数。

如果需要添加排序功能,只需要在Controller里获取排序参数并传递给Model:

// Controller里添加排序参数获取
$sort_by = filter_input(INPUT_GET, 'sort', FILTER_SANITIZE_STRING);
$sort_order = filter_input(INPUT_GET, 'order', FILTER_SANITIZE_STRING);
// 调用Model时传递参数
$products = get_products_by_category($category_id, $pn, PER_PAGE, $sort_by, $sort_order);

然后在视图里添加排序链接:

<!-- 示例:按价格排序的链接 -->
<a href="?<?php echo http_build_query([
    'category_id' => $current_category,
    'page_number' => $pn,
    'sort' => 'price',
    'order' => $sort_order === 'ASC' ? 'DESC' : 'ASC'
]); ?>">
    按价格 <?php echo $sort_order === 'ASC' ? '降序' : '升序'; ?>
</a>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:12:42