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

2024-01-24

这更像是一个“最佳实践”问题,而不是一个实际问题:

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

我通过执行以下操作在控制器之间发送数据:

$controller = new \Acme\myBundle\Controller\DefaultController;
$response = $controller->function();

这工作正常,但我不断遇到一个问题。在控制器中,我将数据传递给我,我需要实例化 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"

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

 $test = $this->get("service.handler")->testFunction();
 $test2 = $this->get("service.definitions")->anotherTestFunction();

我遇到的问题是,如果我调用一个服务内部的函数,然后尝试从该服务内部调用另一个服务,我会收到以下 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

我可以通过使用此函数并调用它而不是使用 $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);    
}

我想我的解决方案“有效”,但它看起来显然不是一种有效的做事方式。

EDIT 2:如果我将其放在类的顶部,然后修改服务调用,它似乎可以工作......仍然不确定这是否是最好的方法。

    protected $container;

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

我会下去控制器即服务 http://symfony.com/doc/current/cookbook/controller/service.html与上述路线。假设您必须调用 3 个方法作为处理的一部分。让我们称呼他们为foo(), bar() and 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);
    }
}

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

services:
    my.foo.service:
        class: Acme\FooBundle\Controller\FooController
        arguments:
            container: "@service_container"

请参阅 Symfony 文档更多细节 http://symfony.com/doc/current/book/service_container.html#creating-configuring-services-in-the-container关于如何构建此条目,包括注入任何依赖项,例如实体管理器或类似的。现在,您可以从容器中获取此实例:

public function yourMainAction()
{
    // ...

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

    // ...

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

同样对于BarController and SomethingController。现在的优点是,可以在应用程序中的任何点(无论是通过上面的容器,还是作为注入的服务)、跨捆绑包提供该服务,而无需自己手动实例化该类并提供任何依赖项。

有关容器等的更多信息,Symfony 文档有好部分 http://symfony.com/doc/2.0/book/service_container.html就可以了(在上面的链接中引用)。

Edit:调整了代码示例以包含将参数传递到服务的详细信息。还增加了一个便利get()从容器中检索服务的方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Symfony2 在包和控制器之间传递数据 的相关文章

随机推荐