PHP 7出现‘Trying to get property of non-object’错误(PHP 5.4可正常运行)
解决PHP7中访问非对象属性的兼容问题
这个问题我遇过不少,本质是PHP7对类型错误的处理比PHP5严格了很多——在PHP5.4里,访问非对象的属性只会触发一个警告,脚本还能继续跑;但到了PHP7及以上版本,这种操作会直接抛出致命错误(Trying to get property of non-object),直接终止脚本执行。
错误根源分析
你的代码里直接在foreach($data[$parent] as $v)循环中访问$v->category_id、$v->category_parent_id等属性,默认假设$v一定是对象,但实际场景中$data[$parent]里的元素可能是数组、null或者其他非对象类型,PHP5.4忽略了这个警告,PHP7就直接报错了。
另外还有个隐性问题:你用了static $i和static $a这两个静态变量,递归调用时它们的状态会一直保留,如果多次调用这个函数,会导致缩进和前缀符号的长度完全混乱,这个也得一起修正。
修复方案
我给你调整后的代码,同时解决兼容问题和逻辑问题:
function get_cat_option($data, $pid, $cid=0, $parent=0, $depth=1){ // 用传递的depth参数代替静态变量$i,控制缩进长度 $tab = str_repeat(" ", $depth); $pusher = "-"; // 用depth计算前缀符号的重复次数,代替静态变量$a $showPusher = str_repeat($pusher, $depth - 1); $html = ''; if(isset($data[$parent]) && !empty($data[$parent])) { $html .= "$tab"; foreach($data[$parent] as $v) { // 核心修复:先检查$v是否为对象,避免非对象访问属性的致命错误 if (!is_object($v)) { continue; // 跳过非对象元素,也可以根据需求做其他处理 } // 递归调用时传递depth+1,实现层级缩进 $child = get_cat_option($data, $pid, $cid, $v->category_id, $depth + 1); $listChild = ""; if($v->category_parent_id == 0) { $listChild = ""; } // 简化选中状态的判断 $selected = ($v->category_id == $pid) ? ' selected' : ''; // 这里补全option的HTML拼接(根据你的业务需求调整) $html .= "<option value='{$v->category_id}'{$selected}>{$showPusher}{$v->category_name}</option>"; $html .= $child; } } return $html; }
关键修改点说明
- 添加对象类型检查:在访问
$v的属性前,用is_object($v)确保只有对象才会执行后续属性访问操作,彻底解决PHP7的致命错误。 - 移除静态变量:改用传递的
$depth参数控制缩进和前缀符号长度,避免多次调用函数时静态变量的状态残留导致格式混乱。 - 补全并简化代码:把未完成的
$selected赋值改成三元表达式,同时规范了HTML拼接的逻辑。
这样修改后,代码在PHP5.4和PHP7+环境下都能正常运行,同时还修复了递归逻辑里的隐性bug。
内容的提问来源于stack exchange,提问作者Mostafarado Rado
相关产品推荐
相关产品推荐

