假设我有一个User
实体:
$user = new User(007);
echo $user->getName(); // display Bond
echo $user->getGender(); // display "Male";
echo $user->getDesignation() // display "Monsieur Bond" or "Mister Bond"
字符串
使用此功能:
public function getDesignation() {
if ($this->getGender() == 'Male') return "Monsieur ".$this->getName();
else return "Madame ".$this->getName();
}
型
我如何使用本实体内的翻译服务来翻译“先生”和“女士”?
翻译服务似乎应该只在Controller内部使用,但我认为在这种情况下,在这个实体内部使用它是合适的。
5条答案
按热度按时间7fhtutme1#
这个问题很老了,但我决定添加一个答案来保存某人的时间。
Symfony从5.2版开始有很好的解决方案:可翻译对象(类似于spackmat的解决方案)
https://symfony.com/blog/new-in-symfony-5-2-translatable-objects
字符串
然后在twig模板中,你可以像这样渲染它:
型
bqf10yzr2#
翻译服务,就像你说的,是一个“服务”,你可以在任何类中使用一个服务(即也将其定义为服务并使用依赖注入器容器)。因此,您几乎可以在任何地方使用翻译器。
但是像aldo said这样的实体不应该有这种责任。在最坏的情况下,如果你真的想在实体内部翻译东西,你可以用一个set方法把翻译器传递给实体,也就是。
字符串
但是我也建议您创建一个类来处理实体之外的问题,例如。使用细枝模板
型
7cwmlq893#
你不应该而且一般来说这是不可能的。根据Single Responsibility Principle,这些实体已经有了它们的用途,即表示数据库上的数据。此外,翻译是一个表示的问题,因此您不太可能希望在实体层解决这样的问题(除非您希望提供以不同语言翻译的实体,这是一个完全不同的问题,甚至不应该使用翻译器来解决)。
重新思考你的逻辑,尝试一些不同的方法。您确定不想在视图层上执行此转换吗?那可能是最好的选择了。否则(如果您的逻辑确实需要在模型级别进行转换),您可以为实体创建一个 Package 类,并创建一个工厂来生成这个“ Package 的实体”;在工厂中,您可以注入Translator服务。
8zzbczxx4#
我遇到了类似的问题,终于找到了这个解决方案。这不是对你的问题的直接回答,因为我也知道一个实体应该与服务无关,比如翻译。所以你应该保持getDesignation函数不变。相反,在表示层(例如,twig)中,您需要翻译法语名称。
字符串
在你的信息里。en.yml
型
j2cgzkjk5#
在过去的几年里,我遇到过几次这个问题,总是找到了一个足够好的解决办法。这一次,我的
getIdentifyingName()
方法在整个项目中被大量使用(比如显式的__toString()
),它必须转换数据层中使用的一些关键字,所以没有优雅的解决方法。我这次的解决方案是一个
TranslateObject
和一个相应的helper服务。TranslateObject
是一个普通对象,它包含一个转换键和一个占位符数组,这些占位符也可以是TranslateObjects,以允许多级转换(比如getIdentifyingNameTranslateObject()
在其中一个占位符中调用另一个相关对象的getIdentifyingNameTranslateObject()
):字符串
助手看起来像这样,并完成工作:
型
然后在Entity中有一个
getIdentifyingNameTranslateObject()
方法返回一个TranslateObject
。型
当我需要返回这样一个转换后的属性时,我需要访问我注入的
TranslateObjectHelper
服务,并像在控制器或任何其他服务中一样使用它的trans()
方法:型
然后我创建了一个小树枝过滤器作为一个简单的助手,像这样:
型
所以在Twig中,我可以这样翻译:
型
最后,我“只”需要找到该实体上的所有
getIdentifyingName()
调用(或Twig中的.identifyingName
),并将它们替换为getIdentifyingNameTranslateObject()
,并调用TranslateObjectHelper
的trans()
方法(或Twig中的translateObject
过滤器)。