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

Laravel 5.2升级至10.20后解密数据出现序列化前缀问题求助

问题分析

Laravel 5.2 的 Encryptable trait 依赖的 Crypt::encrypt() 方法,底层会自动对传入数据执行 serialize() 序列化操作;而 Laravel 10 的 encrypted 类型转换使用的 Crypt::decryptString() 仅负责解密,不会自动反序列化数据。这就导致旧数据库中被序列化后加密的数据,在 Laravel 10 中解密后直接返回序列化格式的字符串(如s:11:"Hello World")。

另外,Laravel 5.2 的 Crypt::decrypt() 方法内部会自动调用 unserialize(),所以当时无需手动处理就能得到原始数据,这也是你在旧版本中能正常获取干净数据的核心原因。

解决方案

方案一:自定义属性访问器/修改器(兼容新旧数据)

如果暂时不想批量修改数据库数据,可以给加密字段自定义属性,同时处理旧数据的反序列化和新数据的正确加密:

use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Support\Facades\Crypt;

protected function myEncryptedAttributeString(): Attribute
{
    return Attribute::make(
        get: function ($value) {
            $decrypted = Crypt::decryptString($value);
            // 判断是否为PHP序列化格式,是的话反序列化
            if (str_starts_with($decrypted, 's:') || str_starts_with($decrypted, 'a:') || str_starts_with($decrypted, 'i:')) {
                return unserialize($decrypted);
            }
            return $decrypted;
        },
        set: function ($value) {
            // 新数据直接加密,不做序列化
            return Crypt::encryptString($value);
        }
    );
}

配置完成后,移除模型中对应的encrypted类型转换项即可。

方案二:批量迁移数据库旧数据(永久解决)

如果希望统一遵循 Laravel 10 的加密规范,可以写一个脚本批量处理数据库中的旧加密数据:

  1. 创建自定义命令脚本:
php artisan make:command MigrateEncryptedData
  1. 编辑生成的命令文件:
<?php

namespace App\Console\Commands;

use App\Models\MyModel;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Crypt;

class MigrateEncryptedData extends Command
{
    protected $signature = 'migrate:encrypted-data';
    protected $description = '迁移旧加密数据至Laravel 10格式';

    public function handle()
    {
        // 分块处理避免内存溢出
        MyModel::chunk(100, function ($models) {
            foreach ($models as $model) {
                // 解密旧数据
                $oldDecrypted = Crypt::decryptString($model->my_encrypted_attribute_string);
                // 反序列化得到原始值
                $originalValue = unserialize($oldDecrypted);
                // 用Laravel 10方式重新加密(不序列化)
                $model->my_encrypted_attribute_string = Crypt::encryptString($originalValue);
                $model->save();
            }
        });

        $this->info('加密数据迁移完成!');
    }
}
  1. 运行命令执行迁移:
php artisan migrate:encrypted-data

迁移完成后,即可正常使用 Laravel 10 的encrypted类型转换配置,无需额外处理。

内容的提问来源于stack exchange,提问作者HelloWorld

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 17:03:35