CodeIgniter致命错误:在布尔值上调用num_rows()方法求助
嘿,这个问题我之前也碰到过!本质上是你的Datatables生成的SQL查询执行失败了,返回了false(布尔值),而不是预期的数据库结果集,所以调用num_rows()的时候就触发了这个致命错误。下面给你一步步排查和解决的方法:
1. 定位问题根源:查询执行失败
错误提示里的num_rows()是在Datatables库的第399行调用的,这说明库内部尝试对一个布尔值(查询失败返回的false)调用结果集方法。最常见的原因是你的SQL查询有语法或逻辑错误,尤其是你用到的子查询部分。
2. 先打印生成的SQL语句调试
在你调用echo $this->datatables->generate();之前,先添加一行代码打印最终生成的SQL:
// 打印Datatables生成的SQL语句 echo $this->datatables->last_query(); exit; // 先看SQL,再执行后续代码
把打印出来的SQL复制到数据库客户端(比如phpMyAdmin、Navicat)直接执行,你大概率会看到具体的错误提示——比如我一眼就注意到你的子查询有问题:
你的子查询
select id, check_in.barcode_num, max(date) as ts from check_in group by check_in.barcode_num在MySQL的严格模式(比如ONLY_FULL_GROUP_BY开启)下是不合法的:id字段既没有被包含在GROUP BY里,也没有用聚合函数处理,这违反了SQL标准。
3. 修复子查询逻辑
如果你的需求是获取每个barcode_num对应的最新(date最大)记录,那需要调整子查询的写法,确保符合SQL规范。修改后的CodeIgniter代码如下:
$this->load->library('datatables'); $this->datatables ->select('ci.id, ci.barcode_num, ci.station, ci.`date`') // 给date加反引号,避免和MySQL关键字冲突 ->from('check_in ci') // 给主表加别名ci,简化代码 ->join('( select barcode_num, max(`date`) as max_date from check_in group by barcode_num ) j', 'ci.barcode_num = j.barcode_num and ci.`date` = j.max_date', 'inner'); // 先验证SQL,再输出结果 // echo $this->datatables->last_query(); echo $this->datatables->generate();
这里的关键改动:
- 子查询只保留
barcode_num和聚合后的max(date),避免了id带来的分组问题 - 给
date字段加了反引号,因为它是MySQL的保留关键字,避免语法冲突 - 给主表加了别名,让代码更清晰
4. 其他排查点
如果调整子查询后还是报错,再检查这几个地方:
- 数据库连接配置是否正确,当前用户有没有
check_in表的查询权限 - 表名、字段名有没有拼写错误(比如
station字段是否存在) - Datatables库的版本是否和你的CodeIgniter版本兼容
5. 添加错误捕获(可选)
为了以后更方便调试,可以在代码里添加数据库错误捕获:
$datatablesResult = $this->datatables->generate(); if (!$datatablesResult) { // 打印数据库错误信息 var_dump($this->db->error()); exit; } echo $datatablesResult;
内容的提问来源于stack exchange,提问作者Fahad Khan

