$this->db->last_query() 只在 save_queries 为 true 且执行了 get()/insert() 等触发方法后才返回当前 sql;未执行查询或 save_queries=false 时返回空或残留语句。

直接说结论: $this->db->last_query() 是最常用、最轻量的 SQL 调试方式,但它只在 save_queries 为 TRUE 且查询已实际执行后才有效;不执行查询(比如只调用 select()、where())就调用它,会返回空或上一条残留语句。
为什么 $this->db->last_query() 有时返回空或错误 SQL?
根本原因在于 CodeIgniter 的查询构造器(Query Builder)是延迟执行的。只有调用 get()、insert()、update()、delete() 等触发执行的方法后,SQL 才真正生成并缓存。
-
$this->db->select('name')->from('users')->where('id', 1);—— 此时还没生成 SQL,last_query()仍为上一次执行的结果 -
$query = $this->db->get('users');—— 执行后才生成SELECT * FROM users WHERE id = 1,此时last_query()才能取到它 - 若配置中
'save_queries' => FALSE(例如生产环境常设为FALSE),last_query()将始终返回空字符串
如何确保每次都能拿到刚写的那条 SQL?
关键是在执行查询后、处理结果前立即捕获,且避免被后续查询覆盖。常见可靠写法:
- 在
get()后立刻调用:$query = $this->db->get('users'); $sql = $this->db->last_query(); echo $sql; - 调试时加
die防止后续逻辑干扰:echo '<pre class="brush:php;toolbar:false;">' . htmlspecialchars($this->db->last_query()) . '</pre>'; die; - 如果模型里封装了查询,记得把
last_query()放在get()或result()之后,不能放在方法末尾随便写
比 last_query() 更全面的调试:启用分析器
当需要看完整查询列表、执行时间、绑定参数(尤其带占位符的查询),$this->output->enable_profiler(TRUE) 比单条 last_query() 更有用,但仅限开发环境。
- 需确保控制器中已加载输出类(默认已加载),且数据库配置中
'db_debug' => TRUE和'save_queries' => TRUE - 在任意位置调用
$this->output->enable_profiler(TRUE),页面底部会显示「Database」面板,列出所有执行过的 SQL 及耗时 - 注意:它不会显示未执行的构造链(如只有
select()没有get()),也不会显示事务内的 prepare 语句
最容易被忽略的一点:CodeIgniter 3 默认开启 save_queries,但很多项目上线前会手动关掉——所以调试时第一反应不该是“函数坏了”,而是先检查 application/config/database.php 里 'save_queries' 的值是否为 TRUE,以及当前环境(ENVIRONMENT)是否导致 db_debug 连带失效。











