CodeIgniter3日志报非对象读title错误但应用运行正常问题排查
报错根本原因
你观察到的“页面功能正常但持续刷Notice日志”的矛盾状态,核心是两类完全独立的请求走了同一个控制器方法,其中一类请求根本拿不到有效的表单对象:
- 你手动测试、用户正常访问的请求,携带的
form_slug是和数据库表单标题匹配的,这时候$form_data是你var_dump里看到的stdClass对象,取值、渲染视图全链路正常,页面功能没有任何问题,也不会触发报错。 - 持续刷入日志的报错请求,对应的是携带无效/不存在
form_slug的请求:比如爬虫批量扫描的无效路径、路由默认兜底请求、带了错误slug的访问。这类请求走数据库查询时匹配不到对应表单,CodeIgniter3的$query->row()在查询无结果时会返回null,这时候你直接执行$form_data->title,就会触发“试图在非对象上获取属性'title'”的Notice。
之所以你没察觉到这些异常请求的影响,是因为:
- PHP对Notice级别的错误不会中断程序执行,就算
$form_data是null,触发报错后$form_data->title只会被赋值为null,程序会继续往下走 - 你代码里视图加载的逻辑本身就有书写错误:
$this->load->view('forms/' . $data);这里把数组$data直接拼接到视图路径里,PHP会把数组转成字面量"Array",正常CI3传视图数据的写法是把$data作为load->view的第二个参数传入。因为路径拼接错误,CI找不到对应视图时会自动兜底加载默认视图,最终渲染出来的页面甚至看不出异常,只有日志会默默记录报错。
可落地的修复方式
- 在控制器增加查询结果的非空判断,从根源上避免对null值取对象属性:
public function view($form_slug) { $form_name = str_replace('-', ' ', $form_slug); $form_data = $this->Form_model->getFormByName($form_name); // 查询无有效结果直接返回404,终止后续执行 if (!$form_data) { show_404(); } $data = array( 'title' => $form_data->title ); // 修正视图加载逻辑,正确传参给视图 $this->load->view('forms/对应表单视图名称', $data); }
- 可以临时在日志里记录触发报错时的请求URI,就能定位到具体是哪些无效路径在持续触发报错,这类请求绝大多数是爬虫的无差别扫描流量。
内容的提问来源于stack exchange,提问作者TheOrdinaryGeek
相关产品推荐
相关产品推荐

