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

Symfony3.4 LTS升级:Translator扩展服务获取全局应用容器问题

在Symfony 3.4中为自定义Translator获取容器的解决方案

你遇到的问题是Symfony版本升级后的典型变化:Symfony 2.x里FrameworkBundle的Translator类继承了ContainerAware,所以能直接通过$this->container访问容器,但到了Symfony 3.4,这个类已经不再持有容器引用,直接调用会抛出未定义属性的错误。下面给你两种可行的解决办法,推荐第二种更符合依赖注入原则的方式:


方法1:注入完整的服务容器

如果确实需要全局容器(不推荐,但满足你的需求),可以通过构造函数注入ContainerInterface:

步骤1:修改自定义Translator类

更新类的构造函数,添加容器参数,并确保正确传递父类所需的参数:

<?php

namespace AppBundle\Translation;

use Symfony\Bundle\FrameworkBundle\Translation\Translator;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Translation\MessageFormatterInterface;
use Symfony\Component\Translation\TranslatorInterface;

class TenantAwareTranslator extends Translator
{
    private $container;

    // 严格匹配Symfony 3.4父类Translator的构造函数参数
    public function __construct(
        TranslatorInterface $translator,
        MessageFormatterInterface $formatter,
        string $locale = null,
        ContainerInterface $container
    ) {
        parent::__construct($translator, $formatter, $locale);
        $this->container = $container;
    }

    protected function loadCatalogue($locale)
    {
        parent::loadCatalogue($locale);
        // 现在可以正常获取容器内的服务了
        $twig = $this->container->get('twig');
        // ... 你的租户数据库翻译加载逻辑
    }
}

步骤2:配置服务定义

在app/config/services.yml(或对应的XML/PHP配置)中,注入容器到自定义Translator服务:

services:
    app.tenant_aware_translator:
        class: AppBundle\Translation\TenantAwareTranslator
        arguments:
            - '@translator.default'       # 父类依赖的基础Translator实例
            - '@translation.formatter.message' # 消息格式化器依赖
            - '%locale%'                  # 应用默认语言
            - '@service_container'        # 注入全局服务容器
        tags:
            - { name: translator }        # 标记为翻译服务,让Symfony识别

方法2:直接注入所需的Twig服务(推荐)

依赖注入的最佳实践是只注入实际需要的服务,而非整个容器,这样代码更清晰,也更容易测试和维护:

步骤1:修改自定义Translator类

直接注入Twig的Environment类:

<?php

namespace AppBundle\Translation;

use Symfony\Bundle\FrameworkBundle\Translation\Translator;
use Symfony\Component\Translation\MessageFormatterInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Twig\Environment;

class TenantAwareTranslator extends Translator
{
    private $twig;

    public function __construct(
        TranslatorInterface $translator,
        MessageFormatterInterface $formatter,
        string $locale = null,
        Environment $twig
    ) {
        parent::__construct($translator, $formatter, $locale);
        $this->twig = $twig;
    }

    protected function loadCatalogue($locale)
    {
        parent::loadCatalogue($locale);
        // 直接使用注入的Twig实例,无需再从容器获取
        // ... 你的租户数据库翻译加载逻辑
    }
}

步骤2:配置服务定义

在services.yml中注入Twig服务:

services:
    app.tenant_aware_translator:
        class: AppBundle\Translation\TenantAwareTranslator
        arguments:
            - '@translator.default'
            - '@translation.formatter.message'
            - '%locale%'
            - '@twig' # 直接注入Twig服务实例
        tags:
            - { name: translator }

关键说明

  • Symfony 3.x开始逐步移除框架类对ContainerAware的依赖,核心目的是降低代码耦合,让依赖关系更明确。
  • 如果你的自定义Translator需要替换Symfony默认的翻译服务,可以将服务ID改为translator,或者调整标签优先级,具体取决于你的应用配置逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:08:26