PHP遍历Session存储对象读取name属性报错解决方法
问题原因
报错的核心原因是存储和读取的操作不匹配:
- 你在向
$_SESSION['logs']存入数据时,手动调用serialize()把Log类的实例转换成了序列化格式的字符串 - 读取遍历
$_SESSION['logs']时,你直接把每个数组元素(也就是序列化后的字符串)当成Log对象,尝试访问name属性,因此触发"尝试在字符串类型值上读取属性"的警告。
额外说明:PHP的Session机制本身已经内置了对象的序列化/反序列化逻辑,不需要手动调用serialize()处理要存入Session的对象,多余的手动序列化反而会导致存进去的值变成字符串而非可直接使用的对象。
修复方案
你可以任选以下一种方案修复:
方案1:适配现有已序列化存储的数据
如果已经有通过旧代码存入Session的历史数据,可以保留存入时的serialize()逻辑,只需要修改读取页data.php的代码,读取时先反序列化还原对象,同时必须提前定义好Log类保证反序列化正常:
<?php // 必须在session_start和反序列化操作前定义Log类 class Log { public $name; public $location; public $activity; } session_start(); // 增加判断避免logs键不存在时报错 if (!empty($_SESSION['logs'])) { foreach ($_SESSION['logs'] as $logStr) { // 反序列化还原为Log对象 $log = unserialize($logStr); echo $log->name . "<br>"; } } ?>
方案2:简化逻辑,移除多余手动序列化(推荐)
这种写法更符合PHP Session的使用习惯,代码更简洁:
- 修改
index.php中存入Session的代码,去掉serialize()调用,直接存入对象:// 把原来的 $_SESSION['logs'][] = serialize($new_log); 替换为 $_SESSION['logs'][] = $new_log; - 修改
data.php的读取逻辑,提前定义Log类后直接遍历访问属性即可:<?php // 提前定义Log类,供PHP自动反序列化Session中的对象使用 class Log { public $name; public $location; public $activity; } session_start(); if (!empty($_SESSION['logs'])) { foreach ($_SESSION['logs'] as $log) { echo $log->name . "<br>"; } } ?>
注意:所有读取存储了自定义类对象的Session的页面,都必须在调用
session_start()前加载好对应类的定义,否则PHP无法正确还原对象,会生成无法正常访问属性的不完整类实例。
内容的提问来源于stack exchange,提问作者Gabriel Dela Peña
相关产品推荐
相关产品推荐

