2015-10-13 3 views
1

У меня есть problème с инициализации переменнойПолучить экземпляр доктрины в конструкторе контроллера

Мой контроллер:

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, в Сконфигурируйте прохождение доктрины службы на мой контроллер 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"]] 
  • ТЕСТ 1 не работает
  • ТЕСТ 2 с ESSAI 1,2,3 (services.yml) doesn'twork
  • ТЕСТ 3 работы

с тестовыми 1, я получаю следующее сообщение об ошибке: Ошибка: Вызов функции члена имеет() на нуль в поставщика \ Symfony \ Symfony \ SRC \ Symfony \ Bundle \ FrameworkBundle \ Controller \ controller.php в строке 291

С ТЕСТА 2 $ EntityManager (аргумент __construct) является NULL

I не читайте ничего против инициализации, в контроллере переменной с экземпляром entitymanager. С Symfony2.3, TEST 2 работает, я думаю.

Я что-то забыл в конфигурации доктрины?

спасибо,

Phil

ответ

1

Как вы расширить класс Symfony\Bundle\FrameworkBundle\Controller\Controller, у вас есть много заинтересованных методов и Particulary getDoctrine.

Итак, я предлагаю вам позвонить непосредственно внутри контроллера (-ов), менеджера сущностей, когда вам это нужно.

public function dispatchUrl(Request $request) 
{ 
    $this->em = $this->getDoctrine()->getManager(); 
    ... // your business logic 
} 

Вариант 3 является лучшим: без обслуживания и без конструктора.

1

Ваш вопрос несколько запутан. Похоже, что у вас есть две идентичные службы. Также неясно, какое тестирование вы выполняете. Вы настроили маршруты для использования сервисов контроллера?

В любом случае, чтобы использовать стандартный контроллер инфраструктуры в качестве службы, вам необходимо ввести контейнер, а также другие ваши сервисы. Ошибка «имеет» указывает, что вы пытаетесь использовать один из методов базового контроллера, который полагается на наличие контейнера. Достаточно легко ввести его:

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

+0

спасибо, ваше решение работает! Но это правда, мне не нужен сервис, поэтому я использую решение @scoolnico – Philalawst

1

http://symfony.com/doc/current/cookbook/controller/service.html

Если вам нужно только, чтобы получить экземпляр менеджера сущностей, просто сделать, как написано @scoolnico, или, если вы действительно хотите, чтобы объявить контроллер в качестве службы прочитайте приведенную выше документацию и не беспокоите класс Controller от FrameworkBundle.

Простой пример здесь (скопирован из документа и изменен):

// src/AppBundle/Controller/HelloController.php 
namespace AppBundle\Controller; 

use Symfony\Component\HttpFoundation\Response; 

class HelloController 
{ 
    private $em; 

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

    public function indexAction($name) 
    { 
     $em = $this->em; 
     ... 
    } 
} 

services.yml:

services: 
    app.hello_controller: 
     class: AppBundle\Controller\HelloController 
     arguments: 
      - @doctrine.orm.entity_manager 
+0

за ваш ответ! Я использую решение @scoolnico, потому что в настоящее время мне не нужно использовать сервис – Philalawst

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, что иногда довольно приятно.

+0

за ваш ответ! – Philalawst

Смежные вопросы