
本文详解 codeigniter 中分页功能失效的典型原因(如误将总记录数设为每页条数),并提供规范、可复用的分页实现方案,涵盖 sql 查询优化、配置关键项修正及安全编码实践。
本文详解 codeigniter 中分页功能失效的典型原因(如误将总记录数设为每页条数),并提供规范、可复用的分页实现方案,涵盖 sql 查询优化、配置关键项修正及安全编码实践。
在 CodeIgniter 中实现数据库分页时,一个常见却极易被忽视的错误是:将 $config['per_page'] 错误地设置为总记录数($finaldata['num_results']),而非期望的每页显示条数(如 10 条)。这会导致分页控件虽正常渲染,但实际查询始终拉取全部数据——因为 LIMIT 的偏移量与行数计算完全失准, pagination 库也因配置矛盾而失去分页意义。
✅ 正确实现步骤(以每页 10 条为例)
1. 分离「总数统计」与「分页查询」
避免执行两次全表查询。应使用 COUNT(*) 获取总记录数,再用带 LIMIT 的 SELECT * 获取当前页数据:
// 步骤①:获取总记录数(仅 COUNT,高效)
$count_sql = "SELECT COUNT(*) AS total FROM list AS a " . $search_condition;
$count_query = $this->db->query($count_sql);
$total_rows = (int) $count_query->row()->total;
// 步骤②:定义分页参数(关键!)
$per_page = 10; // 每页显示条数,固定值,非 $total_rows!
$uri_segment = 3;
$offset = ($this->uri->segment($uri_segment)) ? $this->uri->segment($uri_segment) : 0;
// 步骤③:构造分页查询(使用安全拼接)
$sql = "SELECT * FROM list AS a {$search_condition} LIMIT {$offset}, {$per_page}";
$query = $this->db->query($sql);
⚠️ 注意:
$offset是 CodeIgniter 分页库自动计算的起始位置(从 0 开始),无需手动(page-1)*per_page计算;若启用'use_page_numbers' => TRUE(默认),则 URI 中传的是页码(如/list/2),$offset会由框架自动转换为10(第2页 → 跳过前10条)。
2. 配置 Pagination 库(核心修正点)
确保 per_page 与实际查询的 LIMIT 值严格一致,且 total_rows 准确:
$this->load->library('pagination');
$config = [
'base_url' => site_url('adminuser/list'),
'total_rows' => $total_rows, // ✅ 必须是真实总数
'per_page' => $per_page, // ✅ 必须是每页条数(如 10),绝非 $total_rows!
'uri_segment' => $uri_segment,
'use_page_numbers' => TRUE, // 推荐:URI 显示页码更友好
'num_links' => 5,
'full_tag_open' => '<div class="pagination">',
'full_tag_close' => '</div>',
'cur_tag_open' => '<span class="current">',
'cur_tag_close' => '</span>'
];
$this->pagination->initialize($config);
3. 组装视图数据并渲染
$finaldata = [
'num_results' => $total_rows,
'data' => $query->result_array(),
'pagination' => $this->pagination->create_links()
];
$this->load->view('admin/list', $finaldata);
? 安全与可维护性建议
-
避免字符串拼接 SQL:
$search_condition若含用户输入,必须预处理(如$this->db->escape_like_str()或使用 Query Builder); -
优先使用 Query Builder:更安全、可读性高,例如:
$this->db->select('COUNT(*) as total')->from('list a'); if (!empty($search_condition)) { $this->db->where($search_condition); // 自动转义 } $count = $this->db->get()->row()->total; -
清理冗余变量:如原代码中无意义的
$limit = $finaldata['num_results'],直接用$per_page替代; -
启用错误日志:开发阶段开启
display_errors,快速定位 SQL 语法或配置错误。
通过以上修正,分页将严格按设定(如每页 10 条)工作,URL 如 /adminuser/list/1、/adminuser/list/2 将分别返回第 1–10 条、第 11–20 条数据,create_links() 生成的页码导航也将准确反映数据分布。记住:分页的本质是「限制查询范围」+「告知总数」,二者缺一不可,且参数必须逻辑自洽。











