undefined variable 错误根源在于控制器传入视图的 $data 数组键名与视图中变量名不完全一致,包括拼写、大小写、下划线差异或漏传;需逐字符核对键名,并在控制器中用 var_dump($data) 确认结构。

直接看控制器传了什么、视图用了什么,不匹配就报 Undefined variable。核心不是“怎么避免”,而是“怎么快速定位错在哪一段”。
检查控制器中 $this->load->view() 的第二个参数
这个数组的键名,就是视图里能用的变量名。漏传、拼错、大小写不一致,都会导致视图里访问时未定义。
- 确认
$data数组是否真的包含你视图里写的那个键,比如视图写了$result,控制器就得有$data['result'] = ... - 别用动态键名(如
$data[$key] = ...)却不确保$key一定存在或已赋值 - CI 3 和 CI 4 都不支持在
$data中传对象属性自动展开,必须显式设键名:不能指望$data['user']->name在视图里变成$user->name,得写成$data['user'] = $user
验证视图中变量名和控制器键名是否完全一致
PHP 是区分大小写的,$Result 和 $result 是两个变量;CI 不做任何转换,原样映射。
- 常见错误:控制器传
$data['tb_bills'],视图却写$bills或$TB_BILLS - CI 4 的
return view('xxx', $data)同理,$data键名必须和视图中变量名逐字符一致 - 如果模型返回的是对象,而你希望在视图里用数组方式访问(如
$item['id']),得提前在控制器里转成数组:$data['items'] = json_decode(json_encode($items), true)
在视图里加 isset() 或空合并操作符前先确认问题根源
加 isset($result) 能防止报错,但掩盖了数据没传过来的事实——它只是让页面不崩,不是修复逻辑。
- 临时调试可用:
<?php var_dump($result); ?>直接放在视图开头,看是不是null或NULL,或者根本没输出 - 更可靠的做法是在控制器里加
var_dump($data); exit;,确认数组结构和键名是否符合预期 - 不要在生产环境留
var_dump或print_r,它们可能暴露敏感数据或破坏 HTML 结构
注意模型方法返回值是否为空或非预期类型
即使键名对了,值本身可能是 null、false 或空数组,视图里一旦用到 $result[0]['title'] 这类链式访问,仍会触发“未定义索引”错误。
- 模型方法如
displayDisc()返回null时,$data['result']就是null,视图里foreach($result as ...)会直接报错 - 建议在控制器中做基础校验:
$data['result'] = $this->discussions->displayDisc() ?: []; - CI 4 的
findAll()返回空数组没问题,但 CI 3 的result_array()在查询无结果时返回空数组,而row_array()返回null,这点容易踩坑
最常被忽略的一点:CI 的视图变量注入是纯数组键名映射,没有任何魔法。它不关心你模型里叫什么、数据库字段叫什么,只认控制器传进去的那个键——少一个字母、多一个下划线、大小写错位,就是未定义。











