【问题标题】:PHP-DI is not working in integration with ZendFramework2PHP-DI 不能与 ZendFramework2 集成
【发布时间】:2015-02-23 13:00:29
【问题描述】:

能否请您提示为什么PHP-DI integration with 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(
        ...
    ),
);

config/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

您的任何想法将不胜感激。

【问题讨论】:

  • 为什么不直接使用 zf2 服务管理器呢? framework.zend.com/manual/current/en/modules/…
  • 这是一个很好的问题。老实说,我是 ZendFramework 的新手。我最近才发现SM。对我来说,PHP-DI(带有注释)使用的 DI 方法看起来更接近 Spring @Inject。这就是我坚持下去的原因。我会尝试用 SM 重写并在这里返回结果。

标签: php zend-framework zend-framework2 php-di


【解决方案1】:

它不起作用,因为您使用的是旧的 YAML 语法,而是 since PHP-DI v4.0 the syntax is now PHP

前往文档了解语法:http://php-di.org/doc/definition.html

【讨论】:

  • 啊,现在说得通了,尝试使用提供的操作配置在 zf2 的 vanilla 安装中修复问题,但无法完全解决错误。
  • 我不得不承认这是一个奇怪的边缘情况:/ 基本上现在它是 PHP 配置,配置文件必须返回一个 PHP 数组。这是一个 YAML 文件,所以当它是 included 时,它将返回 null。 PHP-DI 然后将 null 视为空配置,但它可能会显示错误,尽管这是 IMO 非常奇怪的情况。
【解决方案2】:

对于服务:

出厂配置:

        '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'
        ),

【讨论】:

  • 一个问题,服务的使用还是暗示:$serviceManager = $this->getServiceLocator(); $serviceManager->get("MyService")->doSmth();
  • 这个例子是针对一个服务的,但是对于一个控制器来说配置基本上是一样的
  • 我添加了另一个示例,这是否回答了您的问题。控制器不依赖于定位器,只依赖于工厂
  • 顺便说一句,代码和功能看起来非常类似于 Zend\Di ...framework.zend.com/manual/current/en/modules/… ...如果您更喜欢容器而不是定位器,也许您可​​以尝试使用它?
【解决方案3】:

我遵循 Purple Hexagon 给出的建议,这是一个使用 Service Manager 的工作实现:

模块/Morpho/config

...
'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. ServiceManager 提供的依赖注入方法使我的代码依赖于 ServiceManager 本身。通常我不应该关心 bean/对象是如何注入的,因此不应该在我的代码中引用任何类型的容器或 ServiceManager。

我认为PHP-DI 更接近 Java Spring 使用的 bean 注入模型(我认为这很好)。不幸的是,它仍然不适合我。 最后,从容器中获取对象的方法也适用于 PHP-DI。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-08
    • 2015-01-10
    • 1970-01-01
    • 2017-11-05
    • 1970-01-01
    • 2011-12-17
    相关资源
    最近更新 更多