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

Laravel Post模型嵌套数组转扁平数组用于DeepL翻译及回写问题

解决方案:通过路径映射实现嵌套数组的翻译来回

核心思路是在扁平化嵌套数组时,为每个待翻译文本保留其在原数组中的路径标识,翻译完成后再根据路径将结果回填到原数组对应位置,全程只需调用一次DeepL API。

步骤1:实现嵌套数组的扁平化(带路径映射)

在Post模型中添加递归遍历方法,提取所有需要翻译的文本,并以路径字符串作为键(比如blocks.0.text)生成扁平数组:

class Post extends Model
{
    // 假设content是JSON字段,已转为数组
    protected $casts = [
        'content' => 'array',
    ];

    /**
     * 将嵌套的content转为带路径标识的扁平翻译数组
     */
    public function flattenContentForTranslation(): array
    {
        $flatTranslations = [];
        $this->traverseContentNodes($this->content, '', $flatTranslations);
        return $flatTranslations;
    }

    /**
     * 递归遍历content节点,提取待翻译文本
     */
    private function traverseContentNodes(array $nodes, string $parentPath, array &$flat): void
    {
        // 可自定义需要翻译的字段名,灵活调整范围
        $translatableFields = ['text', 'caption', 'description'];

        foreach ($nodes as $key => $value) {
            $currentPath = $parentPath ? "{$parentPath}.{$key}" : (string)$key;

            if (is_array($value)) {
                $this->traverseContentNodes($value, $currentPath, $flat);
            } elseif (is_string($value) && trim($value) !== '' && in_array($key, $translatableFields)) {
                $flat[$currentPath] = $value;
            }
        }
    }
}

步骤2:调用DeepL API翻译扁平数组

使用DeepL SDK(或API请求)一次性翻译整个扁平数组:

// 取出待翻译的Post实例
$post = Post::find($postId);

// 生成带路径的扁平翻译数组
$toTranslate = $post->flattenContentForTranslation();

// 调用DeepL API翻译(示例用官方SDK写法,实际根据你的集成调整)
$translatedResult = \DeepL\Translator::translateText(
    $toTranslate,
    null, // 自动检测源语言
    'zh', // 目标语言
    ['tag_handling' => 'html'] // 若文本含HTML可开启,按需调整
);

// 整理翻译后的结果为「路径=>翻译文本」的数组
$translatedFlat = [];
foreach ($translatedResult as $item) {
    $translatedFlat[array_keys($toTranslate)[$item->index]] = $item->text;
}

步骤3:将翻译结果回填到原嵌套数组

在Post模型中添加回填方法,根据路径字符串定位原数组位置并替换值:

class Post extends Model
{
    // ... 其他代码 ...

    /**
     * 将翻译后的扁平数组回填到原content嵌套结构
     */
    public function fillTranslatedContent(array $translatedFlat): void
    {
        $content = $this->content;

        foreach ($translatedFlat as $path => $translatedText) {
            $keys = explode('.', $path);
            $currentNode = &$content;

            foreach ($keys as $index => $key) {
                // 跳过不存在的路径,避免数组报错
                if (!isset($currentNode[$key])) {
                    break;
                }

                // 到达路径最后一个节点,赋值翻译文本
                if ($index === count($keys) - 1) {
                    $currentNode[$key] = $translatedText;
                } else {
                    $currentNode = &$currentNode[$key];
                }
            }
        }

        $this->content = $content;
    }
}

完整使用流程

// 1. 获取Post
$post = Post::find(1);

// 2. 生成扁平翻译数组
$toTranslate = $post->flattenContentForTranslation();

// 3. 调用DeepL翻译(这里需根据你的实际API集成调整)
$translatedFlat = $this->callDeepLAPI($toTranslate);

// 4. 回填翻译结果
$post->fillTranslatedContent($translatedFlat);

// 5. 保存到数据库
$post->save();

灵活性调整

  • 可修改$translatableFields数组来增减需要翻译的字段类型;
  • 若content结构有特殊节点(比如嵌套深度变化、动态字段),只需调整traverseContentNodes中的遍历逻辑即可适配;
  • 若需要处理多语言版本,可将翻译后的content存储为新字段(比如content_zh),而非覆盖原字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 12:04:55