很多墨水流过Sf2控制器/容器。我面对以下情况:
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
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
public function indexAction()
{
dump(Controller::get('security.token_storage'));
...
显然工作正常。
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我找到了:
在此示例中,控制器扩展了Symfony的基本控制器,使您可以访问服务容器本身。然后,您可以使用get方法从服务容器中找到并检索my_mailer服务。
误解是: - 两个控制器都扩展了基本控制器,它本身扩展了ContainerAware,它实现了设置容器的ContainerAwareInterface。 - 两个控制器都访问相同的公共服务容器。
那么,为什么第二个控制器不起作用呢?
我知道这个问题很老但我不想将控制器作为服务注入,我认为在services.yml中重新声明公共服务是多余的,也是错误的
提前谢谢。
答案 0 :(得分:0)
我自己找到了答案,我希望每个人都能分享同样的情况...... UserUtilsController不起作用,因为它不以这种方式工作。如果你了解它,Symfony架构很有趣。
// 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();
...
#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 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模型之后,上述解决方案几乎是微不足道的。