每次从数据库加载时,我都需要Avalanche Imagine Bundle向我提供我的Image实体的缩略图位置。
正如它在github页面上所说,在控制器中执行此操作非常简单:
$avalancheService = $this->get('imagine.cache.path.resolver');
$cachedImage = $avalancheService->getBrowserPath($object->getWebPath(), 'my_thumb');
问题是,我不想在我的控制器中使用它。我每次从数据库加载它时都需要我的实体调用它,但我无法从我的实体内部访问Symfony服务。正如我发现的那样,我真的应该无法获得服务容器,因为“实体应该只知道自己和其他实体”,但我如何实现我想要的呢?
具体来说,如何调用服务方法并将其值存储在每个实体加载的实体属性中?
答案 0 :(得分:0)
您可以拥有一个实体经理来管理某个实体类型的创建,加载,更新等。
例如,对于FOSUserBundle,您可能希望使用UserManager来创建用户实体,而不是以旧方式执行。
// Good
$user = $container->get('fos_user.user_manager')->createUser();
// Not so good
$user = new User();
这样您就可以将管理委托给另一个类(在本例中为UserManager)并添加额外的控件。
所以假设你有一个实体Foo
。您必须创建一项服务FooManager
,该服务会在创建和加载时自动将Imagine
与Foo
绑定。
实体:
<?php
namespace Acme\DemoBundle\Entity;
class Foo
{
protected $id;
protected $imagine;
public function getId()
{
return $this->id;
}
public function setImagine($imagine)
{
$this->imagine = $imagine;
return $this;
}
public function getImagine()
{
return $this->imagine;
}
public function getBrowserPath()
{
return $this->imagine->getBrowserPath($this->getWebPath(), 'my_thumb')
}
public function getWebPath()
{
return 'the_path';
}
}
经理:
<?php
namespace Acme\DemoBundle\Manager;
class FooManager
{
// Service 'imagine.cache.path.resolver' injected by DIC
protected $imagine;
// Entity repository injected by DIC
protected $repository;
public function __construct($imagine, $repository)
{
$this->imagine = $imagine;
$this->repository = $repository;
}
public function find($id)
{
// Load entity from database
$foo = $this->repository->find($id);
// Set the Imagine service so we can use it inside entities
$foo->setImagine($this->imagine);
return $foo;
}
}
然后你会使用像$foo = $container->get('foo_manager')->find($id);
这样的东西。
当然,你必须稍微调整一下这个类。
不确定这是否是最佳方式,但这是我发现的唯一解决方法,因为我们无法将服务注入实体。