
本文详解 CodeIgniter 手动 SQL 分页常见错误,重点纠正 per_page 与总记录数混淆、未使用 COUNT 查询、LIMIT 参数计算错误等问题,并提供结构清晰、可直接复用的修复方案。
本文详解 codeigniter 手动 sql 分页常见错误,重点纠正 `per_page` 与总记录数混淆、未使用 count 查询、limit 参数计算错误等问题,并提供结构清晰、可直接复用的修复方案。
在 CodeIgniter 中手动编写原生 SQL 实现分页时,一个典型误区是:将每页显示条数(per_page)错误地设为总记录数,导致分页控件虽渲染成功,但实际查询始终拉取全部数据——这正是你代码中 $limit = $finaldata['num_results'] 所引发的核心问题。
此外,原始逻辑存在多处隐患:
- 首次查询
SELECT * ...用于统计总数,效率低下且不必要;应改用COUNT(*); -
$start_limit计算方式($offset-1) * $limit基于页码(page number),但 CodeIgniter 默认分页 URI 段使用偏移量(offset),需确认use_page_numbers配置是否匹配; - 字符串拼接 SQL 易出错且不安全,推荐使用花括号语法或 Query Builder 增强可读性与安全性;
- 未对
$search_condition做空值判断,可能导致语法错误(如WHERE AND ...)。
✅ 正确做法如下(以每页显示 10 条为例):
// 1. 统计总记录数(高效、安全)
$count_sql = "SELECT COUNT(*) AS cnt FROM list AS a " . ($search_condition ?: '');
$count_query = $this->db->query($count_sql);
$total_rows = (int)$count_query->row()->cnt;
// 2. 设置每页数量(固定值,非 total_rows!)
$per_page = 10;
$offset = $this->uri->segment(3, 0); // 获取 URI 第3段作为 offset(如 /adminuser/list/20)
// 3. 执行带分页的主查询
$sql = "SELECT * FROM list AS a {$search_condition} LIMIT {$offset}, {$per_page}";
$query = $this->db->query($sql);
$finaldata = [
'num_results' => $total_rows,
'data' => $query->result_array(),
];
// 4. 配置并初始化分页库
$this->load->library('pagination');
$config = [
'base_url' => site_url('adminuser/list'),
'total_rows' => $total_rows,
'per_page' => $per_page, // ✅ 关键:此处必须是 10,不是 $total_rows
'uri_segment' => 3,
'use_page_numbers' => FALSE, // ⚠️ 若用 offset(如 /list/10),设为 FALSE;若用页码(/list/2),则设 TRUE 并调整 offset 计算
'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);
$finaldata['pagination'] = $this->pagination->create_links();
$this->load->view('admin/list', $finaldata);
? 关键注意事项:
-
永远不要用
COUNT(*)查询后又执行全表SELECT *—— 这会浪费资源,尤其在大数据量场景; -
use_page_numbers设为TRUE时,URI 段表示「页码」(如/list/2表示第2页),此时$offset = ($page - 1) * $per_page;设为FALSE(默认)时,URI 段即为偏移量(如/list/10表示跳过前10条),更直观且无需额外计算; - 务必对
$search_condition做空值校验(如trim($search_condition)或三元判断),避免生成非法 SQL; - 如需更高安全性与可维护性,建议迁移到 CodeIgniter Query Builder(如
$this->db->select()->from()->where()->limit()->get()),自动处理转义与兼容性。
通过以上修正,分页将严格按每页 10 条生效,create_links() 输出的页码导航也将准确对应数据切片,彻底解决“显示全部记录”的问题。











