CodeIgniter 3 中开启数据库查询日志需设 db_debug => TRUE,执行查询后通过 $this->db->queries 获取全部SQL数组,或用 $this->db->last_query() 查看最后一条;生产环境应改用 log_message() 写入日志文件。

CodeIgniter 3 如何开启数据库查询日志并查看执行的 SQL
CodeIgniter 3 默认不记录或输出 SQL 语句,但可以通过开启 db_debug 和启用查询日志功能快速定位问题。关键不是“打印”,而是让框架把每次查询存进 $this->db->queries 数组,并在页面底部显示(开发环境)。
- 确保
application/config/database.php中'db_debug' => TRUE(仅开发环境开启,生产环境必须为FALSE) - 在控制器或模型中执行查询后,直接访问
$this->db->queries可获取所有已执行 SQL 的数组 - 若想在页面底部统一显示(类似 CI2 的 debug bar),需在视图末尾手动输出:
<?php if (ENVIRONMENT === 'development'): ?> <pre><?php print_r($this->db->queries); ?></pre> <?php endif; ?>
-
$this->db->last_query()只返回最近一次查询的 SQL 字符串,适合调试单条语句
CodeIgniter 4 的数据库日志开关与实际输出方式
CI4 完全重构了日志机制,不再依赖 db_debug,而是通过 Logger + Query Bindings + 查询监听器实现。默认不记录 SQL,需要主动配置。
- 在
app/Config/Database.php中设置'DBDebug' => true(注意大小写),这仅影响错误堆栈中的 SQL 显示,不自动记录全部查询 - 真正记录每条 SQL 需要启用查询日志:在数据库配置的
'DSN'或连接参数里加'log_queries' => true(部分驱动如 MySQLi 支持,PDO 不原生支持) - 更可靠的方式是使用事件监听:在
app/Config/Events.php中注册DBQuery事件,捕获$event['sql']和$event['binds'],然后写入日志文件或log_message() - CI4 的
$builder->getCompiledSelect()等方法可预览 SQL,但不包含绑定参数值;要看到完整语句,得手动替换$builder->getBinds()到编译后的 SQL 中
为什么 $this->db->queries 在 CI3 中为空?常见原因
即使开了 db_debug,$this->db->queries 仍为空,大概率是没触发“查询执行”动作,或者被缓存/跳过。
- 使用了
$this->db->cache_on()且命中缓存 → 查询未真实执行,不会进queries数组 - 调用了
$this->db->query()但 SQL 语法错误导致失败 → 错误时该语句**不会**被加入queries,只进query_errors - 在模型构造函数或未加载 DB 类前就访问
$this->db->queries→ 对象未初始化,返回空数组 - 使用了 Query Builder 的链式调用但没调用
->get()、->insert()等执行方法 → SQL 未生成,更不会执行
生产环境不能开 db_debug,怎么安全查 SQL?
生产环境禁用 db_debug 是硬性要求,但排查慢查询或逻辑错误时,仍需看到真实 SQL。不能靠页面输出,得走日志管道。
- CI3:在控制器结尾加
log_message('debug', implode("\n", $this->db->queries)),配合application/config/log.php设置日志等级和路径 - CI4:用
service('logger')->debug('SQL: ' . $builder->getCompiledSelect()),或监听DBQuery事件写入独立日志文件(如writable/logs/queries.log) - 避免记录敏感字段:手动过滤
$builder->getBinds()中的密码、token 等再拼接日志 - 高频接口慎用全量 SQL 日志,建议按 URI 或用户角色条件开启,例如只对管理员 IP 记录
$this->db->queries 表面相似,但底层触发时机、是否包含错误语句、是否受缓存影响都不同。最易忽略的是:CI4 中即使 log_queries => true,PDO 驱动也不会记录绑定后的完整 SQL —— 得自己做参数替换。

















