Zend 3 & Doctrine Невозможно преобразовать службу "BookList \ Controller \ Book" в фабрику; Вы уверены, что предоставили его во время настройки? - PullRequest
0 голосов
/ 26 апреля 2018

Я пытаюсь создать учебный проект, используя Zend и Doctrine. Я могу заставить это приложение работать без Doctrine или базы данных.

Однако недавно я попытался добавить слой базы данных с помощью Doctrine и начал получать сообщение об ошибке: ' Плагин с именем «getServiceLocator» не найден в менеджере плагинов Zend \ Mvc \ Controller \ PluginManager ' , Чтобы исправить это, я обнаружил следующее: Плагин с именем "getServiceLocator" не найден в менеджере плагинов Zend \ Mvc \ Controller \ PluginManager Это почти полностью соответствует моей ситуации. Решение указывает, что getServiceLocator () ограничен, и мне нужно использовать классы Factory для создания экземпляров моих контроллеров

"По сути, вы не должны вводить зависимости в середине время выполнения, но на самом деле зарегистрировать фабрику для вашего контроллера, а затем передать зависимости через конструктор. "

Вот моя проблема: после реализации решения, указанного выше, я получаю следующую ошибку: ' Невозможно разрешить службу "BookList \ Controller \ Book" на заводе; Вы уверены, что указали его во время настройки? '. И я не могу понять, как почему! Что я делаю неправильно? Почему я получаю эту ошибку и почему указанное выше решение не работает для меня?

Вот стек:

#0 C:\wamp64\www\skeleton-application\vendor\zendframework\zend-servicemanager\src\ServiceManager.php(763): Zend\ServiceManager\ServiceManager->getFactory('BookList\\Contro...')
#1 C:\wamp64\www\skeleton-application\vendor\zendframework\zend-servicemanager\src\ServiceManager.php(200): Zend\ServiceManager\ServiceManager->doCreate('BookList\\Contro...')
#2 C:\wamp64\www\skeleton-application\vendor\zendframework\zend-servicemanager\src\AbstractPluginManager.php(141): Zend\ServiceManager\ServiceManager->get('BookList\\Contro...')
#3 C:\wamp64\www\skeleton-application\vendor\zendframework\zend-mvc\src\DispatchListener.php(102): Zend\ServiceManager\AbstractPluginManager->get('BookList\\Contro...')
#4 C:\wamp64\www\skeleton-application\vendor\zendframework\zend-eventmanager\src\EventManager.php(322): Zend\Mvc\DispatchListener->onDispatch(Object(Zend\Mvc\MvcEvent))
#5 C:\wamp64\www\skeleton-application\vendor\zendframework\zend-eventmanager\src\EventManager.php(179): Zend\EventManager\EventManager->triggerListeners(Object(Zend\Mvc\MvcEvent), Object(Closure))
#6 C:\wamp64\www\skeleton-application\vendor\zendframework\zend-mvc\src\Application.php(332): Zend\EventManager\EventManager->triggerEventUntil(Object(Closure), Object(Zend\Mvc\MvcEvent))
#7 C:\wamp64\www\skeleton-application\public\index.php(40): Zend\Mvc\Application->run()
#8 {main}

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

<?php
namespace BookList\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use BookList\Form\BookForm;
use Doctrine\ORM\EntityManager; //For DOCTRINE

class BookController extends AbstractActionController{

    protected $em; //DOCTRINE Entity Manager

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

    public function indexAction(){
        return new ViewModel(array(
            'books' => []; //Do nothing whilst I try to fix factory problem
        ));
    }

}

My Controller Factory:

<?php
namespace BookList\Controller\Factory;

use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
use BookList\Controller\BookController;

class IndexControllerFactory implements FactoryInterface {
    public function __invoke(ContainerInterface $container, $requestedName = "", array $options = null) {
        return new BookController($container->get('Doctrine\ORM\EntityManager'));
    }
}

?>

module.config.php в module \ BookList \ config \ - я закомментировал элемент Invokables и заменил на фабрики элемент в соответствии с инструкциями (вверху):

<?php
namespace BookList;

return array(
        'controllers' => array(
            /*
            'invokables' => array(
                'BookList\Controller\Book' => 'BookList\Controller\BookController',
            ),
            */
            'factories' => array(
                'BookList\Controller\Book' => 'BookList\Controller\Factory\BookListControllerFactory',
            ),

        ),
        'router' => array(
            'routes' => array(
                'book' => array(
                    'type' => 'segment',
                    'options' => array(
                        'route' => '/book[/][:action][/:id]',
                        'constraints' => array(
                            'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                            'id'     => '[0-9]+',
                            ),
                            'defaults' => array(
                                'controller' => 'BookList\Controller\Book',
                                'action'     => 'index',
                            ),
                        ),
                    ),
                ),
            ),
            'view_manager' => array(
                'template_path_stack' => array(
                    'book' => __DIR__ . '/../view',
                ),
            ),
        // Doctrine config
        'doctrine' => array(
            'driver' => array(
                __NAMESPACE__ . '_driver' => array(
                    'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver',
                    'cache' => 'array',
                    'paths' => array(__DIR__ . '/../src/' . __NAMESPACE__ . '/Entity')
                ),
                'orm_default' => array(
                    'drivers' => array(
                        __NAMESPACE__ . '\Entity' => __NAMESPACE__ . '_driver'
                    )
                )
            )
        )
);

И на всякий случай проблема с моим версионированием, это файл Composer.json, который я использовал для установки ZF и Doctrine:

{
    "name": "zendframework/skeleton-application",
    "description": "Skeleton Application for Zend Framework zend-mvc applications",
    "type": "project",
    "license": "BSD-3-Clause",
    "keywords": [
        "framework",
        "mvc",
        "zf"
    ],
    "homepage": "http://framework.zend.com/",
    "minimum-stability": "dev",
    "prefer-stable": true,
    "require": {
        "php": "^5.6 || ^7.0",
        "zendframework/zend-component-installer": "^1.0 || ^0.7 || ^1.0.0-dev@dev",
        "zendframework/zend-mvc": "^3.1.0",
        "zfcampus/zf-development-mode": "^3.0",
        "zendframework/zftool": "dev-master",
        "doctrine/doctrine-orm-module": "^1.1"
    },
    "autoload": {
        "psr-4": {
            "Application\\": "module/Application/src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "ApplicationTest\\": "module/Application/test/"
        }
    },
    "extra": [],
    "scripts": {
        "cs-check": "phpcs",
        "cs-fix": "phpcbf",
        "development-disable": "zf-development-mode disable",
        "development-enable": "zf-development-mode enable",
        "development-status": "zf-development-mode status",
        "post-create-project-cmd": [
            "@development-enable"
        ],
        "serve": "php -S 0.0.0.0:8080 -t public public/index.php",
        "test": "phpunit"
    }
}

1 Ответ

0 голосов
/ 26 апреля 2018

Похоже, вы неправильно пометили класс на своей фабрике контроллеров. В файле module.config.php вы называете фабрику BookListControllerFactory, но в фабрике контроллеров вы называете ее IndexControllerFactory. Попробуйте это:

<?php
namespace BookList\Controller\Factory;

use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
use BookList\Controller\BookController;

class BookListControllerFactory implements FactoryInterface {
    public function __invoke(ContainerInterface $container, $requestedName = "", array $options = null) {
        return new BookController($container->get('Doctrine\ORM\EntityManager'));
    }
}

?>
...