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

如何在Laravel 8中转换PostgreSQL存储的Ruby Hash格式数据

实现方案

你存储的是Ruby生态下ActiveSupport序列化生成的YAML格式数据,要转换为Laravel可用的格式可按以下步骤操作:

1. 安装依赖

使用Symfony的YAML组件处理带自定义标签的YAML内容,Laravel项目默认已包含该组件,未安装的话执行:

composer require symfony/yaml

2. 解析YAML并转换为PHP数组

你存储的YAML中带有!ruby/hash:ActiveSupport::HashWithIndifferentAccess这类Ruby自定义类型标签,需要递归处理转为普通PHP关联数组:

use Symfony\Component\Yaml\Yaml;
use Symfony\Component\Yaml\Tag\TaggedValue;

// 从PostgreSQL中读取原始YAML字符串
$rawYaml = '你的数据库查询得到的YAML内容';

// 解析带自定义标签的YAML
$parsedRaw = Yaml::parse($rawYaml, Yaml::PARSE_CUSTOM_TAGS);

// 递归处理Ruby自定义哈希标签
function transformRubyHash($data) {
    // 匹配Ruby哈希标签,转换为普通数组
    if ($data instanceof TaggedValue && str_starts_with($data->getTag(), '!ruby/hash:')) {
        return transformRubyHash($data->getValue());
    }
    // 递归处理数组内所有元素
    if (is_array($data)) {
        return array_map(fn($item) => transformRubyHash($item), $data);
    }
    return $data;
}

$phpArray = transformRubyHash($parsedRaw);

按你给出的示例数据,转换后得到的数组结构如下:

[
    'accepted' => [
        'number_of_order' => [
            'condition' => 'between_number',
            'value' => '0&5'
        ]
    ],
    'removed' => []
]

3. 调整为目标格式

得到普通PHP数组后,可按业务需求自由修改、补充字段得到你需要的目标结构:

// 补充accepted下的字段
$phpArray['accepted']['last_order_total'] = [
    'condition' => 'between_number',
    'value' => '1000&2000'
];
$phpArray['accepted']['last_order_date'] = [
    'condition' => 'before',
    'value' => '2021-10-01T00:00:00.000Z'
];
$phpArray['accepted']['number_of_order']['value'] = '10&20';

// 补充removed下的字段
$phpArray['removed']['last_order_date'] = [
    'condition' => 'after',
    'value' => '2021-10-14T00:00:00.000Z'
];
$phpArray['removed']['last_order_total'] = [
    'condition' => 'between_number',
    'value' => '1200&1500'
];

4. 输出指定格式

如果要输出你示例中=>格式的字符串,直接调用var_export即可:

echo var_export($phpArray, true);

需要JSON格式的话调用json_encode($phpArray)即可。

5. Laravel模型自动转换(可选)

如果需要在Eloquent模型中自动完成解析转换,可以定义访问器和修改器:

// 访问器:读取字段时自动转为PHP数组
public function getYourFieldNameAttribute($value)
{
    $parsed = Yaml::parse($value, Yaml::PARSE_CUSTOM_TAGS);
    return transformRubyHash($parsed);
}

// 修改器:存储时自动序列化
public function setYourFieldNameAttribute($value)
{
    // 若不需要兼容原有Ruby系统,建议直接转为JSON存入PostgreSQL的jsonb字段,性能更高
    $this->attributes['your_field_name'] = Yaml::dump($value);
}

优化建议

如果后续不再有Ruby程序读写该字段,建议将PostgreSQL中存储该内容的字段类型改为jsonb,批量转换所有历史数据后无需每次读取都解析YAML,还可直接使用PostgreSQL的JSON查询语法操作数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 15:36:01