2015-05-21 2 views
0

У меня есть функция, в которой мне нужны несколько контроллеров. Могу ли я назвать его каким-то другим способом, чем расширить класс, в котором находится эта функция? Вопрос:Функция вызова в другом классе Symfony2

class CategoryController extends Controller 
{ 
    public function getCategoriesAction() 
    { 
     $categories = $this->getDoctrine()->getRepository('ModelBundle:Category')->findAll(); 
     return $categories; 
    } 
} 

Как вызвать эту функцию в PostController?

+0

В 'действия symfony' контроллера возвращает' Response' объекта, а не массивы. Но в 'PostController' вы все еще можете сделать' $ this-> getDoctrine() -> getRepository ('ModelBundle: Category') -> findAll(); ' – Med

+0

@Med Да, я могу это сделать, но дублирование кода - это плохо . Мне нужно вызвать эту функцию 7 раз ( –

+0

Это способ сделать это, и причина, почему услуги и контейнер полезны. Кстати, вы не можете вызывать методы контроллера в других контроллерах, вы должны сначала объявить их как службу. .. Так почему бы не использовать службу доктрины, как предполагается, чтобы ее использовали? – Med

ответ

1

Вы можете определить сервис и впрыснуть менеджер лица в нем, для извлечения данных:

dummy.manager: 
    class: AppBundle\Model\DummyManager 
    arguments: 
     entityManager: "@doctrine.orm.entity_manager" 

В вашей службе, вызовите FindAll() метод:

class DummyManager { 

    /** @var EntityManager */ 
    protected $entityManager; 

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

    public function getCategories(){ 
     return $this->entityManager->getRepository('ModelBundle:Category')->findAll(); 
    } 
} 

И последний шаг, в вашем контроллер:

class CategoryController extends Controller 
{ 
    public function getCategoriesAction() 
    { 
     $categories = $this->container->get('dummy.manager')->getCategories(); 
     //... 
    } 
} 

Надеюсь, это поможет.

+0

Объясните мне, какая разница между '$ categories = $ this-> container-> get ('dummy.manager') -> getCategories();' и '$ categories = $ this-> getDoctrine() -> getRepository ('ModelBundle: Category') -> findAll(); '? Ваш ответ намного сложнее, чем просто получение категорий из доктрины. – Med

+0

Ваш случай прост, потому что findAll() можно вызывать с любого контроллера.если у вас есть собственный метод (findAllActiveCategories и т. д.), и вы хотите, чтобы его использовали разные контроллеры, добавьте его в службу и эту службу можно вызвать в любом месте. –

+0

В сложном случае сервис - это способ его решения, но в этом случае вы можете легко получить от доктрины, зачем создавать другую услугу? Будь проще. – Med

0

Вы не должны определять модельные геттеры на контроллере. Понятие метода getCategoriesAction для контроллера должно быть освобождено от вашего мозга.

Что вы хотите сделать, так это определить это поведение выборки в слое модели. Это можно сделать несколькими путями. Кристиан просто отправил один путь, поэтому я предложу другое.

Вы можете определить репозиторий объектов как службу.

приложение/Config/services.yml

services: 
    model.repository.category: 
     class: ModelBundle\Entity\CategoryRepository 
     factory: ["@doctrine.orm.entity_manager", getRepository] 
     arguments: ['ModelBundle:Category'] 

Тогда в контроллере (предполагается, что это контейнер-контроллер в курсе), вы можете сделать это

$categories = $this->get('model.repository.category')->findAll(); 
+0

Благодарим вас за помощь –

+0

, если у меня нет класса репозитория, я должен создать его пустым? –

+0

Нет, вы можете изменить класс на Doctrine \ ORM \ EntityRepository' –

0

Другой подход, как @Med упомянутый, заключается в том, чтобы объявить ваш контроллер как услугу:

services: 
    categoryController: 
     class: AppBundle\Controller\CategoryController 
     arguments: 
      entityManager: @entityManager 
+0

Вопрос: Если мой класс hsa других методов, это не противоречит правилам или правильному программированию, или я должен создать отдельный класс для вызова метода для всех категорий? –

+0

Ну, лучший способ - создать отдельный класс, чтобы выполнить это, поэтому объяснил вам метод ниже, с сервисом. –

+0

Большое спасибо за помощь :) –

1

Вы также можете использовать чистый PHP с чертами

trait CategoryProvider { 
    public function getCategoriesAction() { 
    $categories = $this->container->get('dummy.manager')>getCategories(); 
    //... 
    } 
} 

После этого вы можете использовать эту особенность в контроллерах

class Controller1 { 

    use CategoryProvider; 

    public function indexAction(){ 
     //... 
     $this->getCategoriesAction(); 
     //... 
    } 
} 

class Controller2 { 

    use CategoryProvider; 

    public function anotherAction(){ 
     //... 
     $this->getCategoriesAction(); 
     //... 
    } 
} 
Смежные вопросы