PHP如何从存储多序列化对象的文本文件中获取对象数组?
解决PHP序列化对象批量存储与读取问题
问题原因
你每次将单个序列化后的Merenda对象直接追加到文件中,导致文件内容是多个独立的序列化字符串拼接在一起。而unserialize()函数只会解析第一个完整的序列化结构,剩余内容会被忽略,因此只能得到单个对象。
解决方案
方案1:存储时维护对象数组(推荐)
修改写入逻辑,每次先读取文件中已有的对象数组,添加新对象后再序列化整个数组写入(覆盖文件而非追加),这样文件里始终是一个完整的序列化数组:
if (!empty($_POST)) { // 初始化对象数组 $merendeList = []; // 读取现有文件内容并反序列化为数组(文件不存在则保持空数组) if (file_exists('merende.txt')) { $serializedData = file_get_contents('merende.txt'); $merendeList = unserialize($serializedData) ?: []; } // 添加新的Merenda对象到数组 $merendeList[] = new Merenda($_POST["name"], $_POST["numberOfDisp"], $_POST["cost"]); // 序列化整个数组并写入文件(覆盖原有内容) file_put_contents('merende.txt', serialize($merendeList)); }
读取时直接反序列化即可得到完整的对象数组:
$serializedData = file_get_contents("merende.txt"); $merendeList = unserialize($serializedData) ?: [];
方案2:解析现有拼接的序列化内容(适配已有文件)
如果已经有了多个序列化字符串拼接的文件,可通过循环逐个解析每个序列化对象:
$serializedData = file_get_contents("merende.txt"); $merendeList = []; $currentOffset = 0; $totalLength = strlen($serializedData); while ($currentOffset < $totalLength) { // 从当前偏移量开始反序列化,同时获取本次解析的长度 $currentObj = unserialize( substr($serializedData, $currentOffset), ['allowed_classes' => ['Merenda']], // 限制允许反序列化的类,提升安全性 $parsedLength ); if ($currentObj === false) { break; // 解析失败则终止循环 } $merendeList[] = $currentObj; $currentOffset += $parsedLength; }
注意:
unserialize()的第三个参数$parsedLength是PHP 7.0及以上版本支持的特性,用于获取本次解析消耗的字符串长度。
内容的提问来源于stack exchange,提问作者Conta
相关产品推荐
相关产品推荐

