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

基于Symfony 6.2与API Platform实现API多语言数据返回方案问询

实现API Platform基于XLF文件的多语言数据返回(Symfony6.2+PHP8.1)

1. 配置Symfony翻译组件

先确认翻译组件已安装(Symfony默认自带,缺失的话执行):

composer require symfony/translation

修改config/packages/translation.yaml,配置翻译路径、默认语言及支持的语种:

framework:
    default_locale: en
    translator:
        default_path: '%kernel.project_dir%/translations'
        fallbacks:
            - en
        providers:
            xliff:
                dsn: 'xliff://%kernel.project_dir%/translations'

在translations目录下创建阿拉伯语翻译文件messages.ar.xlf:

<?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
    <file source-language="en" target-language="ar" datatype="plaintext" original="file.ext">
        <body>
            <trans-unit id="real_madrid.name">
                <source>Real Madrid</source>
                <target>ريال مدريد</target>
            </trans-unit>
            <trans-unit id="real_madrid.description">
                <source>Commonly referred to as Real Madrid, is a Spanish professional football club based in Madrid that currently plays in La Liga.</source>
                <target>يشار إليه عادة باسم ريال مدريد ، وهو ناد إسباني لكرة القدم مقره في مدريد ويلعب حاليًا في الدوري الأسباني.</target>
            </trans-unit>
        </body>
    </file>
</xliff>

2. 自动识别请求语言

创建请求事件订阅器,从Accept-Language请求头自动设置当前请求的语言:

<?php

namespace App\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class LocaleSubscriber implements EventSubscriberInterface
{
    public function onKernelRequest(RequestEvent $event): void
    {
        $request = $event->getRequest();
        if (!$event->isMainRequest()) {
            return;
        }

        // 仅支持预设语种,避免非法参数
        $locale = $request->getPreferredLanguage(['en', 'ar']);
        $request->setLocale($locale);
    }

    public static function getSubscribedEvents(): array
    {
        return [
            KernelEvents::REQUEST => ['onKernelRequest', 20],
        ];
    }
}

3. 在实体类中实现翻译逻辑

假设你的API资源实体是App\Entity\Club,修改实体类,通过构造注入翻译服务,在getter方法中返回翻译后的值:

<?php

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Contracts\Translation\TranslatorInterface;

#[ApiResource]
#[ORM\Entity]
class Club
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    private ?int $id = null;

    // 数据库存储原始英文内容
    #[ORM\Column(type: 'string', length: 255)]
    private ?string $name = null;

    #[ORM\Column(type: 'text')]
    private ?string $description = null;

    private TranslatorInterface $translator;

    // 构造注入翻译服务
    public function __construct(TranslatorInterface $translator)
    {
        $this->translator = $translator;
    }

    // 返回翻译后的名称
    public function getName(): ?string
    {
        return $this->translator->trans('real_madrid.name', [], 'messages');
    }

    // 返回翻译后的描述
    public function getDescription(): ?string
    {
        return $this->translator->trans('real_madrid.description', [], 'messages');
    }

    // 数据库操作相关的原始字段方法
    public function setName(string $name): self
    {
        $this->name = $name;
        return $this;
    }

    // 后台需要获取原始内容时调用
    public function getOriginalName(): ?string
    {
        return $this->name;
    }

    public function setDescription(string $description): self
    {
        $this->description = $description;
        return $this;
    }

    public function getOriginalDescription(): ?string
    {
        return $this->description;
    }

    public function getId(): ?int
    {
        return $this->id;
    }
}

4. 测试API

发送请求时携带Accept-Language头指定语言,比如用curl测试阿拉伯语:

curl -H "Accept-Language: ar" http://your-api-domain/clubs/1

返回结果即为阿拉伯语版本:

{
  "id": 1,
  "name": "ريال مدريد",
  "description": "يشار إليه عادة باسم ريال مدريد ، وهو ناد إسباني لكرة القدم مقره في مدريد ويلعب حاليًا في الدوري الأسباني."
}

可选优化:动态翻译键

如果每个实体的翻译键不同,可在实体中新增字段存储翻译键,比如$nameTranslationKey,然后在getter中动态调用:

#[ORM\Column(type: 'string', length: 255)]
private ?string $nameTranslationKey = 'real_madrid.name';

public function getName(): ?string
{
    return $this->translator->trans($this->nameTranslationKey, [], 'messages');
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 07:34:54