Symfony2在bundle和controller之间传递数据

gre*_*reg 5 bundle controller symfony

这是一个"最佳实践"问题,而不是实际问题:

我正在研究Symfony 2中的一个项目,我已经构建了一个包来处理我的所有web服务.基本上,一个控制器获取一些JSON数据,将其发送到另一个控制器以检查它是否与描述的格式匹配,然后关闭到另一个控制器以处理数据库调用并最终返回到初始控制器以返回JSON响应.

我通过这样的方式在控制器之间发送数据:

$controller = new \Acme\myBundle\Controller\DefaultController;
$response = $controller->function();
Run Code Online (Sandbox Code Playgroud)

这工作正常,但我一直遇到一个问题.在控制器中我将数据传递给我需要实例化AppKernel并调用启动函数以使任何Symfony函数工作.这对我来说似乎有点愚蠢,这让我相信我可能做错了.

任何建议或提示赞赏!

编辑/更新 感谢大家的评论.我已将控制器设置为服务,服务正在运行但我仍需要在从服务内部调用服务时手动启动/实例化内核.

#config.yml
# API Services
services:
service.handler:
    class: Acme\APIBundle\Controller\ServicesController
    arguments:
        container: "@service_container"

service.definitions:
    class: Acme\APIBundle\Controller\DefinitionController
    arguments:
        container: "@service_container"
Run Code Online (Sandbox Code Playgroud)

从另一个捆绑控制器,我可以从这些服务中的任何一个调用函数没有问题:

 $test = $this->get("service.handler")->testFunction();
 $test2 = $this->get("service.definitions")->anotherTestFunction();
Run Code Online (Sandbox Code Playgroud)

我遇到问题的地方是如果我在一个服务中调用一个函数,然后尝试从该服务内部调用另一个服务我得到以下PHP错误

Fatal error: Call to a member function get() on a non-object in /vendor/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php on line 188
Run Code Online (Sandbox Code Playgroud)

我可以通过使用此函数并调用它而不是使用$ this来避免该错误

    public function bootKernel(){
//boot kernel
    $controller = new \Acme\myBundle\Controller\DefaultController; 
    $kernel = new \AppKernel('dev', true);$kernel->loadClassCache(); 
    $kernel->boot(); 
    $controller->setContainer($kernel->getContainer());
    return($controller);    
}
Run Code Online (Sandbox Code Playgroud)

我想我的解决方案"有效",但它似乎并不是一种有效的方法.

编辑2: 如果我把它放在班级的顶部然后修改服务调用它似乎工作...仍然不确定这是否是最好的做事方式.

    protected $container;

public function __construct($container) {
    $this->container= $container;
}
Run Code Online (Sandbox Code Playgroud)

ric*_*age 10

我将按照以上方式进入控制器即服务路线.假设您必须在处理过程中调用3种方法.让我们给他们打电话foo(),bar()something().这些方法中的每一个都在单独的控制器中

namespace Acme\DemoBundle\Controller;

class FooController
{
    public function __construct($container, ...)
    {
        $this->container = $container;
        // ... deal with any more arguments etc here
    }

    public function foo($params)
    {
        // ...
        return $x;
    }

    protected function get($service)
    {
        return $this->container->get($service);
    }
}
Run Code Online (Sandbox Code Playgroud)

同样适用于bar()something()方法,每个都在自己的控制器中.然后,将它们作为服务添加到您的应用程序中.例如在你的config.yml(其他方法可用):

services:
    my.foo.service:
        class: Acme\FooBundle\Controller\FooController
        arguments:
            container: "@service_container"
Run Code Online (Sandbox Code Playgroud)

有关如何构造此条目的更多详细信息,请参阅Symfony文档,包括注入任何依赖项(如实体管理器或类似项).现在,您可以从容器中获取此实例:

public function yourMainAction()
{
    // ...

    $newData = $this->get("my.foo.service")->fooAction($someData);

    // ...

    return new Response(json_encode($newData), ...);
}
Run Code Online (Sandbox Code Playgroud)

同样地,BarControllerSomethingController.现在的优势在于,可以在应用程序中的任何位置(无论是通过上面的容器,还是作为注入的服务)跨服务器提供此服务,而无需自己手动实例化类并提供任何依赖性.

有关容器等的更多信息,Symfony文档有一个很好的部分(在上面的链接中引用).

编辑:调整代码示例以包括将参数传递到服务的详细信息.还添加了一种方便的get()方法来从容器中检索服务.