你能告诉我为什么PHP-DI与Zend Framework 2的集成不适合我吗(用Apache/2.4.9(Win64)PHP/5.5.12和Apache/2.2.22(Win32)PHP/55.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',
'DIZendFramework2',
),
'module_listener_options' => array(
'module_paths' => array(
'./module',
'./vendor',
),
),
);
?>
module/Morpho/config.module.config.php:
<?php
return array(
'service_manager' => array(
'factories' => array(
'DIContainer' => function() {
$builder = new DIContainerBuilder();
$builder->addDefinitionsFromFile("config/di.yml");
return $builder->build();
},
),
),
'router' => array(
...
),
'controllers' => array(
...
),
'view_manager' => array(
...
),
);
config/di.yml:
MorphoServicePartOfSpeechService:
class: MorphoServicePhpMorphyPartOfSpeechService
模块/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 'ZendModuleManagerExceptionRuntimeException'
with message 'Module (DIZendFramework2) could not be initialized.' in vendorzendframeworkzendframeworklibraryZendModuleManagerModuleManager.php:195
Stack trace:
0 vendorzendframeworkzendframeworklibraryZendModuleManagerModuleManager.php(169): ZendModuleManagerModuleManager->loadModuleByName(Object(ZendModuleManagerModuleEvent))
1 vendorzendframeworkzendframeworklibraryZendModuleManagerModuleManager.php(96): ZendModuleManagerModuleManager->loadModule('DIZendFramewor...')
2 [internal function]: ZendModuleManagerModuleManager->onLoadModules(Object(ZendModuleManagerModuleEvent))
3 vendorzendframeworkzendframeworklibraryZendEventManagerEventManager.php(468):
call_user_func(Array, Object(ZendModuleManagerModuleEvent))
4 vendorzendframeworkzendframeworklibraryZendEventManagerEventManager.php(207): ZendEventM in vendorzendframeworkzendframeworklibraryZendModuleManagerModuleManager.php on line 195
如果您有任何想法,我们将不胜感激。
它不起作用,因为您使用的是旧的YAML语法,但由于PHP-DI v4.0,现在的语法是PHP。
前往文档了解语法:http://php-di.org/doc/definition.html
对于服务:
出厂配置:
'factories' => array(
'MyService' => 'ApplicationFactoryMyService',
),
工厂等级:
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;
}
}
class 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(
'ApplicationControllerPartOfSpeechController' => 'ApplicationFactoryPartOfSpeechControllerFactory'
),
我遵循了Purple Hexagon给出的建议,下面是一个使用Service Manager:的工作实现
模块/Morpho/config:
...
'service_manager' => array(
'services' => array(
"PartOfSpeechService" => new MorphoServicePhpMorphyPartOfSpeechService(),
),
),
...
module/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);
}
}
为什么我不喜欢这个:
- 我必须使用一个"伪"代码来获得serviceManager。这是"伪",因为这与我的应用程序的业务逻辑根本无关
- ServiceManager提供的依赖注入方法使我的代码依赖于ServiceManager本身。通常,我不应该关心如何注入bean/对象,因此不应该在代码中引用任何类型的容器或ServiceManager
我认为PHP-DI更接近JavaSpring使用的bean注入模型(我认为这很好)。不幸的是,它仍然不适用于我。最后,从容器中获取对象的方法也在PHP-DI中工作。