php - 替换/装饰 `translation.reader`

标签 php symfony symfony4

我修复了一个错误,但看起来我已经关闭了:p

我只想用我自己的类替换服务 Symfony\Component\Translation\Reader\TranslationReader (translation.reader)。事实上我想知道如果我想要的话如何替换SF4的任何服务

translation.reader::addLoader() 通常由框架调用,但如果我用自己的类装饰 addLoader 则不会被调用。

你能告诉我如何放弃替换我自己的服务吗?

https://github.com/symfony/symfony/issues/28843

受影响的 Symfony 版本:4.1.6

描述
无法装饰translation.reader(我想更改默认的i18n文件加载过程)

如何重现

复制/调整Symfony\Component\Translation\Reader\TranslationReaderApp\Translation\Reader\TranslationReader

关注https://symfony.com/doc/current/service_container/service_decoration.html

修改services.yaml

Symfony\Component\Translation\Reader\TranslationReader: ~

App\Translation\Reader\TranslationReader:
    decorates: Symfony\Component\Translation\Reader\TranslationReader

#translation.reader: '@App\Translation\Reader\TranslationReader'

没有别名:新服务将被忽略 使用别名:read() 被触发,但不是 addLoader()

这是生成的注入(inject)文件getTranslationReaderService.php:

<?php

use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;

// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
// Returns the private 'App\Translation\Reader\TranslationReader' shared autowired service.

include_once $this->targetDirs[3].'/vendor/symfony/translation/Reader/TranslationReaderInterface.php';
include_once $this->targetDirs[3].'/src/Translation/Reader/TranslationReader.php';

return $this->privates['App\Translation\Reader\TranslationReader'] = new \App\Translation\Reader\TranslationReader();

默认情况下它看起来像:

use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;

// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
// Returns the private 'translation.reader' shared service.

include_once $this->targetDirs[3].'/vendor/symfony/translation/Reader/TranslationReaderInterface.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Reader/TranslationReader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/LoaderInterface.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/ArrayLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/FileLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/PhpFileLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/YamlFileLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/XliffFileLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/PoFileLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/MoFileLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/QtFileLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/CsvFileLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/IcuResFileLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/IcuDatFileLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/IniFileLoader.php';
include_once $this->targetDirs[3].'/vendor/symfony/translation/Loader/JsonFileLoader.php';

$this->privates['translation.reader'] = $instance = new \Symfony\Component\Translation\Reader\TranslationReader();

$a = ($this->privates['translation.loader.yml'] ?? $this->privates['translation.loader.yml'] = new \Symfony\Component\Translation\Loader\YamlFileLoader());
$b = ($this->privates['translation.loader.xliff'] ?? $this->privates['translation.loader.xliff'] = new \Symfony\Component\Translation\Loader\XliffFileLoader());

$instance->addLoader('php', ($this->privates['translation.loader.php'] ?? $this->privates['translation.loader.php'] = new \Symfony\Component\Translation\Loader\PhpFileLoader()));
$instance->addLoader('yaml', $a);
$instance->addLoader('yml', $a);
$instance->addLoader('xlf', $b);
$instance->addLoader('xliff', $b);
$instance->addLoader('po', ($this->privates['translation.loader.po'] ?? $this->privates['translation.loader.po'] = new \Symfony\Component\Translation\Loader\PoFileLoader()));
$instance->addLoader('mo', ($this->privates['translation.loader.mo'] ?? $this->privates['translation.loader.mo'] = new \Symfony\Component\Translation\Loader\MoFileLoader()));
$instance->addLoader('ts', ($this->privates['translation.loader.qt'] ?? $this->privates['translation.loader.qt'] = new \Symfony\Component\Translation\Loader\QtFileLoader()));
$instance->addLoader('csv', ($this->privates['translation.loader.csv'] ?? $this->privates['translation.loader.csv'] = new \Symfony\Component\Translation\Loader\CsvFileLoader()));
$instance->addLoader('res', ($this->privates['translation.loader.res'] ?? $this->privates['translation.loader.res'] = new \Symfony\Component\Translation\Loader\IcuResFileLoader()));
$instance->addLoader('dat', ($this->privates['translation.loader.dat'] ?? $this->privates['translation.loader.dat'] = new \Symfony\Component\Translation\Loader\IcuDatFileLoader()));
$instance->addLoader('ini', ($this->privates['translation.loader.ini'] ?? $this->privates['translation.loader.ini'] = new \Symfony\Component\Translation\Loader\IniFileLoader()));
$instance->addLoader('json', ($this->privates['translation.loader.json'] ?? $this->privates['translation.loader.json'] = new \Symfony\Component\Translation\Loader\JsonFileLoader()));

return $instance;

你可以看到,当我进行装饰时,加载器没有被注入(inject)...

最佳答案

我不确定这是否是您问题的根源,但这里有一些评论。希望这能帮助您找到解决方案,即使我实际上没有给出您问题的完整答案。

1) Symfony 中的某些翻译服务在缓存预热阶段被调用。每当您更改配置或执行 bin/console cache:clear 时,您将看到这些类已运行,并且它们在您的 var/cache/<env>/translations/ 中生成翻译。文件夹。

2) 您可以尝试确保在您的缓存中, var/cache/<env>/Container<...>/getTranslation_ReaderService.php 加载的类是你的,而不是像这样的默认值:

$this->privates['translation.reader'] = 
    new \Symfony\Component\Translation\Reader\TranslationReader();

3)我在dev中也遇到了类似的问题环境,我试图替换 Symfony\Component\Translation\Translator使用我自己的服务,并且一开始没有设法调用我的方法。部分解释是,当启用 Symfony Profiler 时,Symfony 会执行类似以下操作(在 src<env>DebugProjectContainer.php> 中):

$this->services['translator'] = new \Symfony\Component\Translation\DataCollectorTranslator(
    ($this->privates['translator.default'] ?? $this->getTranslator_DefaultService())
);

DataCollectorTranslator它本身是它作为构造函数参数获取的任何翻译器的包装器。

我知道这不是一个完美的答案,但希望这能帮助您找到解决方案。

关于php - 替换/装饰 `translation.reader`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52839966/

相关文章:

image - symfony 4 webpack + encore 在模板中处理图像更多信息

javascript - 我想使用 jquery 将输入值存储在数组中

PHP 每小时日历,通过存储在数据库中的时间戳运行

php - 如何让当前用户进入我的实体类?

symfony - Webpack 安可 : How to include js from/vendor and use globally?

php - 服务中的 Symfony4 findAll 返回空数组

php - 使用 pdo 时数据未插入数据库

php - 如何在 WordPress 中创建自定义页面?

symfony - 如何使用 docker 将 Symfony4 连接到 mysql

mysql - 将 native SQL 转换为 Doctrine 2 DQL - 自引用多对多