我对变量
的初始化有疑问我的控制器:
namespace SB\FrontendBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\EntityManager;
use Mie\FrontendBundle\Entity\Product;
class FrontendController extends Controller
{
protected $em;
public function __construct(EntityManager $entityManager = null)
{
$this->em = $this->getDoctrine()->getManager(); //--->TEST 1
$this->em = $entityManager; //--->TEST2
}
public function dispatchUrl(Request $request)
{
$this->em = $this->getDoctrine()->getManager(); //--->TEST 3
$product = new Product();
$product->setName('A Foo Bar');
$product->setPrice('19.99');
$product->setDescription('Lorem ipsum dolor');
$this->em->persist($product);
$this->em->flush();
die();
}
}
在我的services.yml中,配置将doctrine服务传递给我的控制器FrontendController
parameters:
mie.frontend.controller.frontend.class: Mie\FrontendBundle\Controller\FrontendController
services:
# ---> ESSAI 1
mie.frontend.controller:
class: "%mie.frontend.controller.frontend.class%"
arguments:
- "@doctrine.orm.entity_manager"
# ---> ESSAI 2
mie.frontend.controller:
class: "%mie.frontend.controller.frontend.class%"
arguments: [ @doctrine.orm.entity_manager ]
# ---> ESSAI 3
# mie.frontend.controller:
# class: "%mie.frontend.controller.frontend.class%"
# calls:
# - [setEntityManager, ["@doctrine.orm.entity_manager"]]
使用TEST 1,我收到以下错误: 错误:调用成员函数has()为null 在vendor \ symfony \ symfony \ src \ Symfony \ Bundle \ FrameworkBundle \ Controller \ Controller.php第291行
使用TEST 2 $ entityManager(__construct的参数)为NULL
我没有读取任何与控制器中的实体初始化的实体操作的初始化。 我认为,使用Symfony2.3,TEST 2可以正常工作。
我是否忘记了学说的配置?
感谢,
菲尔
答案 0 :(得分:3)
由于要求在ctor中获得原则,你应该像http://symfony.com/doc/current/cookbook/controller/service.html#defining-the-controller-as-a-service那样:
<强> FrontendController.php 强>
<?php
class FrontendController /* extends Controller // no need for this */
{
/**
* @var EntityManagerInterface
*/
protected $em;
public function __construct(EntityManagerInterface $entityManager) {
$this->em = $entityManager;
}
}
<强> services.yml 强>
services:
front_controller:
class: ...\FrontendController
arguments:
entityManager: "@doctrine.orm.default_entity_manager"
<强>的routing.yml 强>
homepage:
path: /
defaults:
_controller: frontend_controller:yourAction
作为一种小型的最佳实践方法,我尝试将所有控制器作为服务,并且永远不会扩展Controller
,因为在将容器注入ContainerAware
时会不必要地打开上下文。正如您所看到的那样,单元测试是可能的,而不使用有时相当不错的WebTestCase
。
答案 1 :(得分:1)
在扩展课程Symfony\Bundle\FrameworkBundle\Controller\Controller
时,您有许多感兴趣的方法,特别是getDoctrine
。
因此,我建议您在需要时直接在控制器操作(实体管理器)内部调用。
public function dispatchUrl(Request $request)
{
$this->em = $this->getDoctrine()->getManager();
... // your business logic
}
选项3是最好的:没有服务,也没有构造函数。
答案 2 :(得分:1)
你的问题有些令人困惑。看来你有两个相同的服务。目前还不清楚你在做什么样的测试。您是否已将路由配置为使用控制器服务?
无论如何,要将标准框架控制器用作服务,您需要注入容器以及其他服务。 &#34;有&#34;错误似乎表明您正在尝试使用依赖于容器的基本控制器方法之一。注入它很容易:
mie.frontend.controller:
class: Mie\FrontendBundle\Controller\FrontendController
calls: [[setContainer, ['@service_container']]]
arguments:
- '@doctrine.orm.entity_manager'
基本上,容器负责所有基本功能。使用构造函数注入来注入特定于控制器本身的任何内容。
然后您的路由需要指定服务而不是控制器类。基本上少一个:在_controller参数中。
project_game_export:
path: /export
methods: [GET,POST]
defaults:
_controller: sportacus_project_game_export_controller:exportAction
http://symfony.com/doc/current/cookbook/controller/service.html
答案 3 :(得分:1)
http://symfony.com/doc/current/cookbook/controller/service.html
如果您只需要获取实体管理器的实例,只需按@scoolnico编写,或者如果您确实要将控制器声明为服务,请阅读上述文档,并且不要打扰{来自FrameworkBundle的{1}}类..
这里的简单示例(从文档中复制并修改):
killall
services.yml:
Controller