首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在包和控制器之间传递数据的Symfony2

在包和控制器之间传递数据的Symfony2
EN

Stack Overflow用户
提问于 2012-03-03 00:37:23
回答 2查看 12.4K关注 0票数 5

与其说这是一个实际的问题,不如说这是一个“最佳实践”问题:

我正在Symfony 2中做一个项目,我已经构建了一个包来处理我所有的‘ve服务。基本上,一个控制器获取一些JSON数据,将其发送到另一个控制器以检查它是否符合所描述的格式,然后转到另一个控制器来处理数据库调用,最后返回到初始控制器返回一个JSON响应。

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

代码语言:javascript
复制
$controller = new \Acme\myBundle\Controller\DefaultController;
$response = $controller->function();

这是正确的,但我经常遇到一个问题。在控制器中,我向数据传递数据,我需要实例化AppKernel并调用引导函数,使任何Symfony函数都能工作。这在我看来有点傻,这让我相信我可能做错了。

如有任何建议或建议,敬请欣赏!

编辑/更新谢谢大家的评论。我已经将控制器设置为服务,服务正在工作,但在从服务内部调用服务时,仍然需要手动引导/实例化内核。

代码语言:javascript
复制
#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"

然后,从另一个包控制器中,我可以从这些服务中的任何一个调用函数,而不存在任何问题:

代码语言:javascript
复制
 $test = $this->get("service.handler")->testFunction();
 $test2 = $this->get("service.definitions")->anotherTestFunction();

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

代码语言:javascript
复制
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

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

代码语言:javascript
复制
    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);    
}

我想我的解决方案“可行”,但这显然不是一种有效的方法来做事情。

编辑2: --如果我把它放在类的顶部,然后修改服务调用,它看起来是有效的.但仍不确定这是否是做事情的最佳方式。

代码语言:javascript
复制
    protected $container;

public function __construct($container) {
    $this->container= $container;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-03-04 20:58:12

我会沿着控制员即服务路线走上面的路。假设您必须调用3种方法作为处理的一部分。我们叫他们foo()bar()something()。这些方法中的每一种都位于单独的控制器中:

代码语言:javascript
复制
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);
    }
}

bar()something()方法也是如此,每个方法都在各自的控制器中。然后,将它们作为服务添加到应用程序中。例如在您的config.yml (其他方法可用):

代码语言:javascript
复制
services:
    my.foo.service:
        class: Acme\FooBundle\Controller\FooController
        arguments:
            container: "@service_container"

关于如何构造这个条目,请参阅更多细节的Symfony文档,包括注入任何依赖项,如实体管理器或类似的。现在,您可以从容器中获得这个实例:

代码语言:javascript
复制
public function yourMainAction()
{
    // ...

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

    // ...

    return new Response(json_encode($newData), ...);
}

同样,BarControllerSomethingController也是如此。现在的优点是,该服务可以在应用程序中的任何点(无论是通过上面的容器,还是作为注入的服务)跨包提供,而不需要自己手动实例化类并提供任何依赖项。

有关容器等的更多信息,Symfony文档上有一个良好剖面 (在上面的链接中引用)。

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

票数 10
EN

Stack Overflow用户

发布于 2012-03-04 20:46:24

我建议使用控制器作为服务

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9542293

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档