You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 02:50:52