
本文详解 codeigniter 手动编写 sql 分页时常见的逻辑错误,重点纠正“全量查询代替分页”“per_page 与总记录数混淆”等关键问题,并提供结构清晰、可直接复用的分页实现代码。
本文详解 codeigniter 手动编写 sql 分页时常见的逻辑错误,重点纠正“全量查询代替分页”“per_page 与总记录数混淆”等关键问题,并提供结构清晰、可直接复用的分页实现代码。
在 CodeIgniter 中手动构建分页逻辑时,一个典型误区是:误将总记录数(num_rows())直接赋值给每页显示条数(per_page),导致分页器认为“每页显示全部数据”,从而失去分页意义。您提供的代码中存在多个关键问题:
-
首次查询未统计总数,而是查了全表数据:
$query = $this->db->query($SQL)返回全部记录,浪费性能且无法获取准确总数; -
$limit被错误设为总记录数:$limit = $finaldata['num_results']导致per_page等于总条数,分页控件仅显示“第1页”,无翻页效果; -
$start_limit计算错误:使用$offset-1但未定义$offset来源,且 CodeIgniter 分页默认从第0页开始(use_page_numbers = TRUE时才从1开始),易引发偏移错位; - SQL 拼接不安全且可读性差:直接拼接字符串易引入 SQL 注入风险,且缺乏可维护性。
✅ 正确做法如下(以每页显示 10 条为例):
// Step 1:先获取满足条件的总记录数(使用 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;
// Step 2:配置分页参数(核心:per_page = 10,非 total_rows!)
$this->load->library('pagination');
$config = [
'base_url' => site_url('adminuser/list'),
'total_rows' => $total_rows,
'per_page' => 10, // ✅ 固定每页10条
'uri_segment' => 3,
'use_page_numbers' => TRUE,
'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);
// Step 3:计算当前页偏移量(CodeIgniter 自动处理,无需手动算 start_limit)
$offset = ($this->uri->segment(3)) ? $this->uri->segment(3) : 0;
// Step 4:执行带 LIMIT 的分页查询(推荐使用 Query Builder 更安全)
$sql = "SELECT * FROM list AS a {$search_condition} LIMIT ?, ?";
$query = $this->db->query($sql, [$offset, $config['per_page']]);
$data = $query->result_array();
// 组装视图数据
$finaldata = [
'data' => $data,
'num_results'=> $total_rows,
'pagination' => $this->pagination->create_links()
];
$this->load->view('admin/list', $finaldata);? 关键注意事项:
- ✅ 始终用
COUNT(*)获取总数,而非SELECT *后调用num_rows(); - ✅
per_page必须是固定值(如10),绝不可等于$total_rows; - ✅ 使用
?占位符 + 参数绑定($this->db->query($sql, $params))替代字符串拼接,防止 SQL 注入; - ✅ 若启用
'use_page_numbers' => TRUE,URL 将为/list/1、/list/2,此时$offset应为(page_number - 1) * per_page—— 但 CodeIgniter 的uri_segment(3)已自动返回页码,$this->pagination内部会完成转换,开发者无需手动计算; - ⚠️ 避免在生产环境直接拼接
$search_condition,建议改用 Query Builder 的where()、like()等方法动态构建条件。
通过以上修正,即可稳定实现每页 10 条、支持多页跳转、安全高效的 CodeIgniter 分页功能。


















