【发布时间】:2016-04-21 12:05:42
【问题描述】:
我正在开发一个 Symfony 2.7 WebApp。我创建的其中一个捆绑包包括一项提供一些与用户相关的东西的服务,例如userHasPurchases().
问题是,包含Twig Extesion 会破坏另一个服务:
AppShopService
namespace AppShopBundle\Service;
use AppBundle\Entity\User;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
...
class AppShopService {
protected $user;
public function __construct(TokenStorageInterface $tokenStorage, ...) {
$this->user = $tokenStorage->getToken() ? $tokenStorage->getToken()->getUser() : null;
...
}
public function userHasPurchases(User $user) {
$user = $user ? $user : $this->user;
$result = $user...
return result;
}
}
AppShopBundle\Resources\config\services.yml
services:
app_shop.service:
class: AppShopBundle\Service\AppShopService
arguments:
- "@security.token_storage"
- ...
到目前为止一切正常:AppShopServices 是使用当前用户创建的,userHasPurchases() 按预期工作。
现在我添加了一个 Twig 扩展,以便能够在我的模板中使用 userHasPurchases():
树枝扩展
namespace AppShopBundle\Twig;
use AppShopBundle\Service\AppShopService;
class AppShopExtension extends \Twig_Extension {
private $shopService;
public function __construct(AppShopService $shopService) {
$this->shopService = $shopService;
}
public function getName() {
return 'app_shop_bundle_extension';
}
public function getFunctions() {
$functions = array();
$functions[] = new \Twig_SimpleFunction('userHasPurchases', array(
$this,
'userHasPurchases'
));
return $functions;
}
public function userHasPurchases($user) {
return $this->shopService->userHasPurchases($user);
}
}
在 AppShopBundle\Resources\config\services.yml 中包含扩展
services:
app_shop.service:
class: AppShopBundle\Service\AppShopService
arguments:
- "@security.token_storage"
- ...
app_shop.twig_extension:
class: AppShopBundle\Twig\AppShopExtension
arguments:
- "@app_shop.service"
tags:
- { name: twig.extension }
在包含Twig Extension、AppShopService 及其方法userHasPurchases 后不再起作用。问题是,AppShopService 的构造函数不再设置user,因为$tokenStorage->getToken() 现在返回null。
这怎么可能?除了Twig Extension,我什么都没改变。一旦我从services.yml 中删除Twig Extension,一切都会再次正常工作。
我唯一的猜测是,Twig Extension 的创建是在任何安全性之前完成的。但为什么呢?
知道这里可能出了什么问题吗?
【问题讨论】:
-
一般来说,你不希望在构造函数中获取用户。在创建对象之前,您永远不会真正知道安全组件是否已经完成了它。所以只需添加一个 MyService::getUser 并在需要时调用它。省去一些时间上的麻烦。
-
不要在构造函数中与 tokenStorage 交互,而只能在 `userHasPurchases`` 方法中交互
标签: php symfony twig twig-extension