最常见原因是没指定表名或漏掉from(),get()默认查NULL表导致空结果;必须显式调用from()或传表名给get(),且返回对象需用result()等方法取数据。

CodeIgniter 3 的 $this->db->get() 为什么查不到数据?
最常见原因是没指定表名,或者漏掉了 from()。CodeIgniter 3 的查询构建器不是“链式调用即执行”,select()、where() 这些只是拼条件,真正触发查询的是 get() 或 get_compiled_select() —— 但 get() 默认查 NULL 表,结果就是空结果集,不报错也不提示。
- 必须显式写
$this->db->from('users')->get(),或把表名传给get('users') -
get()返回的是对象(CI_DB_result),不是数组;要取数据得调result()、row()或result_array() - 如果只想要 SQL 字符串用于调试,用
get_compiled_select('users'),它不执行,只生成语句
CodeIgniter 3 中 where() 的数组参数和字符串参数区别在哪?
数组形式自动转义值,安全;字符串形式完全不处理,容易被注入,也容易因引号/空格出错。但字符串形式能写更复杂的条件,比如字段比较、函数调用。
- 安全写法:
$this->db->where(['status' => 'active', 'deleted' => 0])→ 自动加引号、转义 - 需要字段对比时才用字符串:
$this->db->where('created_at > updated_at'),否则写成数组会变成`created_at` = 'updated_at' - 混合场景用
where()+or_where(),但注意括号逻辑:CI 3 不自动加括号,多条件组合建议用group_start()/group_end()
CodeIgniter 3 查询构建器的 limit() 和 offset() 顺序会影响结果吗?
会。CI 3 是按调用顺序拼 SQL 的,limit(10)->offset(20) 生成 LIMIT 10 OFFSET 20(标准 PostgreSQL/MySQL 8.0+ 语法),但旧版 MySQL(5.7 及之前)只认 LIMIT 20, 10。CI 3 默认适配后者,所以实际执行的是 LIMIT 20, 10 —— 也就是跳过 20 条取 10 条。
- 想明确控制,直接用
limit(10, 20),第二个参数是 offset,这是最稳妥的写法 -
offset()单独调用时,必须在limit()之后,否则会被忽略(CI 3 内部只在生成 SQL 时读取最近一次的 limit+offset 配对) - 分页时别依赖
count_all_results()后再手动算 offset,它会重置查询条件(比如丢掉where),要用count_all_results(FALSE)保持条件
为什么 $this->db->insert_batch() 插入中文乱码或失败?
根本原因不是构建器本身,而是数据库连接字符集没设对。CI 3 的 insert_batch() 会把数组转成单条 INSERT INTO ... VALUES (),(),(),但如果连接层用的是 latin1,哪怕表字段是 utf8mb4,批量插入时整条 SQL 也会被当拉丁文解析。
- 检查
application/config/database.php里的charset和dbcollat,必须设为'utf8mb4'和'utf8mb4_unicode_ci' - 确认 MySQL 服务端已启用
utf8mb4:连上后执行SHOW VARIABLES LIKE 'character_set%';,重点看character_set_client、connection、results是否都是utf8mb4 -
insert_batch()对空数组静默失败(不报错也不插入),建议插入前加if (empty($data)) return FALSE;
where(),但忘了 get(),它就真的一声不吭;还有字符集配置藏在 database.php 里,出问题时第一反应总去查模型代码,其实该先盯住那两行配置。









