Zend Framework — PHP-DI не работает в интеграции с ZendFramework2

Не могли бы вы дать намек, почему Интеграция PHP-DI с Zend Framework 2 у меня не работает (воспроизводится с Apache / 2.4.9 (Win64) PHP / 5.5.12 и Apache / 2.2.22 (Win32) PHP / 5.3.13).

composer.json:

{
"require": {
"php": ">=5.3.3",
"zendframework/zendframework": "2.3.5",
"mnapoli/php-di": "4.4.6",
"mnapoli/php-di-zf2": "0.3.0",
...
},
...

Config \ application.config.php:

<?php
return array(
'modules' => array(
'Morpho',
'DI\ZendFramework2',
),
'module_listener_options' => array(
'module_paths' => array(
'./module',
'./vendor',
),
),
);
?>

модуль / Morpho / config.module.config.php:

<?php
return array(
'service_manager' => array(
'factories' => array(
'DI\Container' => function() {
$builder = new DI\ContainerBuilder();
$builder->addDefinitionsFromFile("config/di.yml");
return $builder->build();
},
),
),
'router' => array(
...
),
'controllers' => array(
...
),
'view_manager' => array(
...
),
);

конфиг / di.yml:

Morpho\Service\PartOfSpeechService:
class: Morpho\Service\PhpMorphyPartOfSpeechService

модуль / Morpho / SRC / Morpho / Controller / PartOfSpeechController:

class PartOfSpeechController extends AbstractRestfulController {
...
/**
* @Inject
* @var PartOfSpeechService
*/
public $partOfSpeechService;

public function processPostData(Request $request) {
$partsOfSpeech = $this->partOfSpeechService->getPartsOfSpeech("test", "en_EN");
return new JsonModel($partsOfSpeech);
}
}

При запуске этого кода под Apache каждый раз, когда я получаю:

PHP Fatal error:  Uncaught exception 'Zend\ModuleManager\Exception\RuntimeException'
with message 'Module (DI\ZendFramework2) could not be initialized.' in \vendor\zendframework\zendframework\library\Zend\ModuleManager\ModuleManager.php:195
Stack trace:
0 \vendor\zendframework\zendframework\library\Zend\ModuleManager\ModuleManager.php(169): Zend\ModuleManager\ModuleManager->loadModuleByName(Object(Zend\ModuleManager\ModuleEvent))
1 \vendor\zendframework\zendframework\library\Zend\ModuleManager\ModuleManager.php(96): Zend\ModuleManager\ModuleManager->loadModule('DI\ZendFramewor...')
2 [internal function]: Zend\ModuleManager\ModuleManager->onLoadModules(Object(Zend\ModuleManager\ModuleEvent))
3 \vendor\zendframework\zendframework\library\Zend\EventManager\EventManager.php(468):
call_user_func(Array, Object(Zend\ModuleManager\ModuleEvent))
4 \vendor\zendframework\zendframework\library\Zend\EventManager\EventManager.php(207): Zend\EventM in \vendor\zendframework\zendframework\library\Zend\ModuleManager\ModuleManager.php on line 195

Любые ваши мысли будут по достоинству оценены.

0

Решение

Для обслуживания:

заводская конфигурация:

        'factories' => array(
'MyService' => 'Application\Factory\MyService',
),

Фабричный класс:

class MyService implements FactoryInterface
{

public function createService(ServiceLocatorInterface $serviceManager)
{
$purifier = new MyService($serviceManager->get('MyAwesomeDependency'));
return $purifier;
}
}

Для контроллера:

ControllerFactory.php:

class PartOfSpeechControllerFactory
{
public function __invoke($serviceLocator)
{
// Service locator here is the ControllerManager so get ServiceManager
$serviceManager = $serviceLocator->getServiceLocator();

$controller = new PartOfSpeechController($serviceManager->get('PartOfSpeechService'));

return $controller;
}
}

Класс PartOfSpeechController.php

class PartOfSpeechController extends AbstractRestfulController {protected $partOfSpeechService;

public function __construct(PartOfSpeechService $partOfSpeechService)
{
$this->partOfSpeechService = $partOfSpeechService;
}public function processPostData(Request $request) {
$var = $this->partOfSpeechService->serviceMethod();
}
}

Конфиг для контроллера:

'factories' => array(
'Application\Controller\PartOfSpeechController' => 'Application\Factory\PartOfSpeechControllerFactory'
),
0

Другие решения

Это не работает, потому что вы используете старый синтаксис YAML, но начиная с PHP-DI v4.0, синтаксис теперь PHP.

Перейдите к документации, чтобы узнать о синтаксисе: http://php-di.org/doc/definition.html

1

Я последовал предложению Purple Hexagon и вот за работой реализация с использованием Service Manager:

модуль / Morpho / конфигурации:

...
'service_manager' => array(
'services' => array(
"PartOfSpeechService" => new Morpho\Service\PhpMorphyPartOfSpeechService(),
),
),
...

модуль / Morpho / SRC / Morpho / Controller / PartOfSpeechController.php:

class PartOfSpeechController extends AbstractRestfulController {
...
public function processPostData(Request $request) {
$serviceManager = $this->getServiceLocator();
$partsOfSpeech = $serviceManager->get("PartOfSpeechService")->getPartsOfSpeech($request->getPost("phrase"),
$request->getPost("language"));
return new JsonModel($partsOfSpeech);
}
}

Почему мне не нравится это:

  1. Я должен использовать «фиктивный» код для получения serviceManager. Это «пустышка», потому что это никак не связано с бизнес-логикой моего приложения.
  2. Подход Dependency Injection, предоставляемый ServiceManager, делает мой код зависимым от самого ServiceManager. Как правило, мне не важно, как вводится bean / object, и поэтому я не должен ссылаться на какой-либо контейнер или ServiceManager в моем коде.

Я думаю PHP-DI гораздо ближе к модели внедрения бина, используемой в Java Spring (я считаю, это хорошо). К сожалению, это все еще не работает для меня.
И наконец, подход получения объекта из контейнера работал и в PHP-DI.

0
По вопросам рекламы [email protected]