与其说这是一个实际的问题,不如说这是一个“最佳实践”问题:
我正在Symfony 2中做一个项目,我已经构建了一个包来处理我所有的‘ve服务。基本上,一个控制器获取一些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);
}我想我的解决方案“可行”,但这显然不是一种有效的方法来做事情。
编辑2: --如果我把它放在类的顶部,然后修改服务调用,它看起来是有效的.但仍不确定这是否是做事情的最佳方式。
protected $container;
public function __construct($container) {
$this->container= $container;
}发布于 2012-03-04 20:58:12
我会沿着控制员即服务路线走上面的路。假设您必须调用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);
}
}bar()和something()方法也是如此,每个方法都在各自的控制器中。然后,将它们作为服务添加到应用程序中。例如在您的config.yml (其他方法可用):
services:
my.foo.service:
class: Acme\FooBundle\Controller\FooController
arguments:
container: "@service_container"关于如何构造这个条目,请参阅更多细节的Symfony文档,包括注入任何依赖项,如实体管理器或类似的。现在,您可以从容器中获得这个实例:
public function yourMainAction()
{
// ...
$newData = $this->get("my.foo.service")->fooAction($someData);
// ...
return new Response(json_encode($newData), ...);
}同样,BarController和SomethingController也是如此。现在的优点是,该服务可以在应用程序中的任何点(无论是通过上面的容器,还是作为注入的服务)跨包提供,而不需要自己手动实例化类并提供任何依赖项。
有关容器等的更多信息,Symfony文档上有一个良好剖面 (在上面的链接中引用)。
编辑:调整代码示例以包括向服务传递参数的详细信息。还添加了一个方便的get()方法来从容器中检索服务。
发布于 2012-03-04 20:46:24
我建议使用控制器作为服务。
https://stackoverflow.com/questions/9542293
复制相似问题