Symfony2 在控制器中获取 public 服务
Symfony2 get public services in controller
Sf2 周围流了很多墨水 controller/container。我面临以下情况:
app/console container:debug security
...
> 4
[container] Information for service security.token_storage
Service Id security.token_interface
Class Symfony\Component\Security\Core\Authentication\Token ...
...
Public yes
LoginBundle\DefaultController.php
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
public function indexAction()
{
dump(Controller::get('security.token_storage'));
...
显然可以正常工作。
LoginBundle\UserUtilsController
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class UserUtilsController extends Controller
{
public function getRoleById()
{
dump(Controller::get('security.token_storage'));
...
抛出:Error: Call to a member function get() on a non-object
在Sf2 Book - Service container中我发现:
In this example, the controller extends Symfony's base Controller, which gives you access to the service container itself. You can then use the get method to locate and retrieve the my_mailer service from the service container.
误区是:
- 两个控制器都扩展了基本控制器,后者本身扩展了 ContainerAware,后者实现了设置容器的 ContainerAwareInterface。
- 两个控制器访问相同的 public 服务容器。
那么,为什么第二个控制器不起作用?
我知道这个问题很老,但我不想将控制器作为服务注入,我认为在 services.yml[=17 中重新声明 public 服务是多余和错误的=]
提前致谢。
我自己找到了答案,我想分享给每个处于相同情况的人...
UserUtilsController 不起作用,因为它不是以这种方式工作的。如果您了解 Symfony 架构,它会很有趣。
LoginBundle\Controller\UserUtilsController
// For this job we don't need to extends any class..
class UserUtilsController
{
// but we need a property for injecting the service in it
private $token;
// Now let's inject service into our property $token
public function __construct($token)
{
$this->token = $token;
}
// It's not done but let pretend it is and let's use it
public function getRoleById()
{
...
return $this->token->getToken()->getRoles();
...
services.yml
#here it's the magic
services:
# this is a new services container
user.loggeduser_utils:
# this is my class (second class)
class: LoginBundle\Controller\UserUtilsController
# this is how I feed my _construct argument
arguments: ["@security.token_storage"]
所以我只是在我的新 class 中注入一个现有服务。
现在,要使用它,我们必须先调用 class:
LoginBundle\Controller\DefaultController.php
class DefaultController extends Controller
{
public function indexAction()
{
// because my class is now a service container we call in this way
$userRoleId = $this->get('user.loggeduser_utils');
...
在理解了 Sf2 DI 模型之后,上面的这个解决方案几乎是微不足道的。
Sf2 周围流了很多墨水 controller/container。我面临以下情况:
app/console container:debug security
...
> 4
[container] Information for service security.token_storage
Service Id security.token_interface
Class Symfony\Component\Security\Core\Authentication\Token ...
...
Public yes
LoginBundle\DefaultController.php
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
public function indexAction()
{
dump(Controller::get('security.token_storage'));
...
显然可以正常工作。
LoginBundle\UserUtilsController
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class UserUtilsController extends Controller
{
public function getRoleById()
{
dump(Controller::get('security.token_storage'));
...
抛出:Error: Call to a member function get() on a non-object
在Sf2 Book - Service container中我发现:
In this example, the controller extends Symfony's base Controller, which gives you access to the service container itself. You can then use the get method to locate and retrieve the my_mailer service from the service container.
误区是: - 两个控制器都扩展了基本控制器,后者本身扩展了 ContainerAware,后者实现了设置容器的 ContainerAwareInterface。 - 两个控制器访问相同的 public 服务容器。
那么,为什么第二个控制器不起作用?
我知道这个问题很老,但我不想将控制器作为服务注入,我认为在 services.yml[=17 中重新声明 public 服务是多余和错误的=]
提前致谢。
我自己找到了答案,我想分享给每个处于相同情况的人... UserUtilsController 不起作用,因为它不是以这种方式工作的。如果您了解 Symfony 架构,它会很有趣。
LoginBundle\Controller\UserUtilsController
// For this job we don't need to extends any class..
class UserUtilsController
{
// but we need a property for injecting the service in it
private $token;
// Now let's inject service into our property $token
public function __construct($token)
{
$this->token = $token;
}
// It's not done but let pretend it is and let's use it
public function getRoleById()
{
...
return $this->token->getToken()->getRoles();
...
services.yml
#here it's the magic
services:
# this is a new services container
user.loggeduser_utils:
# this is my class (second class)
class: LoginBundle\Controller\UserUtilsController
# this is how I feed my _construct argument
arguments: ["@security.token_storage"]
所以我只是在我的新 class 中注入一个现有服务。
现在,要使用它,我们必须先调用 class:
LoginBundle\Controller\DefaultController.php
class DefaultController extends Controller
{
public function indexAction()
{
// because my class is now a service container we call in this way
$userRoleId = $this->get('user.loggeduser_utils');
...
在理解了 Sf2 DI 模型之后,上面的这个解决方案几乎是微不足道的。