基于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
相关产品推荐
相关产品推荐

