Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/252.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Zend 2:在插件中获取服务定位器_Php_Zend Framework2_Factory_Service Locator - Fatal编程技术网

Php Zend 2:在插件中获取服务定位器

Php Zend 2:在插件中获取服务定位器,php,zend-framework2,factory,service-locator,Php,Zend Framework2,Factory,Service Locator,我想在我的自定义插件中获取服务定位器。我通过Module.php中的工厂创建它: public function getControllerPluginConfig() { return [ 'factories' => [ 'Application\Plugin\AppPlugin' => function($serviceManager) { $serviceLocator = $serviceMa

我想在我的自定义插件中获取服务定位器。我通过Module.php中的工厂创建它:

public function getControllerPluginConfig() {
    return [
        'factories' => [
            'Application\Plugin\AppPlugin' => function($serviceManager) {

                $serviceLocator = $serviceManager->getServiceLocator();
                $appPlugin = new \Application\Plugin\AppPlugin();
                $appPlugin->setLocator($serviceLocator);
                return $appPlugin;
            }  
        ]
    ];
}
…和我的插件:

<?php

namespace Application\Plugin;

use Zend\Mvc\Controller\Plugin\AbstractPlugin;

class AppPlugin extends AbstractPlugin {

    protected $locator;

    public function getAppInfo() {

        $config = $this->locator->get('Config');
    }

   /**
    * Set Service Locator
    * @param \Zend\ServiceManager\ServiceManager $locator
    */
    public function setLocator($locator) {
        $this->locator = $locator;
    }
}
…我得到一个错误:

Fatal error: Call to a member function get() on a non-object in /vagrant/app/module/Application/src/Application/Plugin/AppPlugin.php on line 13
Call Stack
#   Time    Memory  Function    Location
1   0.0027  232104  {main}( )   ../index.php:0
2   0.6238  3166904 Zend\Mvc\Application->run( )    ../index.php:21
3   1.4410  5659112 Zend\EventManager\EventManager->trigger( )  ../Application.php:314
4   1.4410  5659112 Zend\EventManager\EventManager->triggerListeners( ) ../EventManager.php:205
5   1.4411  5660872 call_user_func ( )  ../EventManager.php:444
6   1.4411  5661440 Zend\Mvc\DispatchListener->onDispatch( )    ../EventManager.php:444
7   1.4505  5704600 Zend\Mvc\Controller\AbstractController->dispatch( ) ../DispatchListener.php:93
8   1.4505  5705080 Zend\EventManager\EventManager->trigger( )  ../AbstractController.php:118
9   1.4505  5705080 Zend\EventManager\EventManager->triggerListeners( ) ../EventManager.php:205
10  1.4507  5716656 call_user_func ( )  ../EventManager.php:444
11  1.4507  5716784 Zend\Mvc\Controller\AbstractActionController->onDispatch( ) ../EventManager.php:444
12  1.4508  5717504 Application\Controller\IndexController->indexAction( )  ../AbstractActionController.php:82
13  1.4641  5727768 Application\Plugin\AppPlugin->getAppInfo( ) ../IndexController.php:21
但是,如果我从控制器传递服务定位器,它可以正常工作:

$appPlugin = new AppPlugin();
$appPlugin->setLocator($this->getServiceLocator());
$appPlugin->getAppInfo(); 

如果有人能解释我做错了什么,我会很高兴的。谢谢。

您不能直接在控制器中实例化该类,您需要使用“Application\plugin\AppPlugin”键将其从控制器插件管理器中取出

$pluginManager = $this->getPluginManager();
$appPlugin = $pluginManager->get('Application\Plugin\AppPlugin');
$appPlugin->getAppInfo();
或者,您可以将方法更改为:

public function getAppInfo() 
{
    $serviceManager = $this->controller->getServiceLocator();
    $config = $serviceManager->get('Config');
}

您不能直接在控制器中实例化该类,您需要使用“Application\plugin\AppPlugin”键将其从控制器插件管理器中取出

$pluginManager = $this->getPluginManager();
$appPlugin = $pluginManager->get('Application\Plugin\AppPlugin');
$appPlugin->getAppInfo();
或者,您可以将方法更改为:

public function getAppInfo() 
{
    $serviceManager = $this->controller->getServiceLocator();
    $config = $serviceManager->get('Config');
}

您不能直接在控制器中实例化该类,您需要使用“Application\plugin\AppPlugin”键将其从控制器插件管理器中取出

$pluginManager = $this->getPluginManager();
$appPlugin = $pluginManager->get('Application\Plugin\AppPlugin');
$appPlugin->getAppInfo();
或者,您可以将方法更改为:

public function getAppInfo() 
{
    $serviceManager = $this->controller->getServiceLocator();
    $config = $serviceManager->get('Config');
}

您不能直接在控制器中实例化该类,您需要使用“Application\plugin\AppPlugin”键将其从控制器插件管理器中取出

$pluginManager = $this->getPluginManager();
$appPlugin = $pluginManager->get('Application\Plugin\AppPlugin');
$appPlugin->getAppInfo();
或者,您可以将方法更改为:

public function getAppInfo() 
{
    $serviceManager = $this->controller->getServiceLocator();
    $config = $serviceManager->get('Config');
}

如果可能,您不应该尝试访问除工厂之外的任何类中的ServiceLocator。这样做的主要原因是,如果ServiceLocator被注入到您的类中,您现在不知道该类的依赖项是什么,因为它现在可能包含任何内容

关于依赖项注入,您有两个基本选择:构造函数注入或setter注入。根据经验,总是更喜欢构造函数注入。Setter注入应该只用于可选的依赖项,而且它还使代码更加模糊,因为类现在是可变的。如果您使用纯粹的构造函数注入,那么您的依赖项是不可变的,并且您可以始终确信它们会存在

另外,通常最好使用具体的工厂类,而不是使用闭包,因为闭包不能被操作码缓存,而且如果配置数组包含闭包,也不能被缓存

有关如何设置类以实现
FactoryInterface

话虽如此,为了本次讨论的目的,让我们继续使用闭包工厂示例。我们没有注入ServiceManager,而是注入了配置数组(这仍然有点过于依赖上帝;最好是注入您需要的配置的特定键,或者更好的是,注入一个实例化的类)

在这里,插件被修改为采用构造函数中的配置。我假设这个插件代码只是一个概念证明,除了返回配置外,您还可以使用插件做一些有用的事情,但希望这确实显示了注入插件依赖项的模式

<?php

namespace Application\Plugin;

use Zend\Mvc\Controller\Plugin\AbstractPlugin;

class AppPlugin extends AbstractPlugin {

    protected $config;

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

    public function getAppInfo() {
        return $this->config;
    }

}

如果可能,您不应该尝试访问除工厂之外的任何类中的ServiceLocator。这样做的主要原因是,如果ServiceLocator被注入到您的类中,您现在不知道该类的依赖项是什么,因为它现在可能包含任何内容

关于依赖项注入,您有两个基本选择:构造函数注入或setter注入。根据经验,总是更喜欢构造函数注入。Setter注入应该只用于可选的依赖项,而且它还使代码更加模糊,因为类现在是可变的。如果您使用纯粹的构造函数注入,那么您的依赖项是不可变的,并且您可以始终确信它们会存在

另外,通常最好使用具体的工厂类,而不是使用闭包,因为闭包不能被操作码缓存,而且如果配置数组包含闭包,也不能被缓存

有关如何设置类以实现
FactoryInterface

话虽如此,为了本次讨论的目的,让我们继续使用闭包工厂示例。我们没有注入ServiceManager,而是注入了配置数组(这仍然有点过于依赖上帝;最好是注入您需要的配置的特定键,或者更好的是,注入一个实例化的类)

在这里,插件被修改为采用构造函数中的配置。我假设这个插件代码只是一个概念证明,除了返回配置外,您还可以使用插件做一些有用的事情,但希望这确实显示了注入插件依赖项的模式

<?php

namespace Application\Plugin;

use Zend\Mvc\Controller\Plugin\AbstractPlugin;

class AppPlugin extends AbstractPlugin {

    protected $config;

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

    public function getAppInfo() {
        return $this->config;
    }

}

如果可能,您不应该尝试访问除工厂之外的任何类中的ServiceLocator。这样做的主要原因是,如果ServiceLocator被注入到您的类中,您现在不知道该类的依赖项是什么,因为它现在可能包含任何内容

关于依赖项注入,您有两个基本选择:构造函数注入或setter注入。根据经验,总是更喜欢构造函数注入。Setter注入应该只用于可选的依赖项,而且它还使代码更加模糊,因为类现在是可变的。如果您使用纯粹的构造函数注入,那么您的依赖项是不可变的,并且您可以始终确信它们会存在

另外,通常最好使用具体的工厂类,而不是使用闭包,因为闭包不能被操作码缓存,而且如果配置数组包含闭包,也不能被缓存

有关如何设置类以实现
FactoryInterface

话虽如此,为了本次讨论的目的,让我们继续使用闭包工厂示例。我们没有注入ServiceManager,而是注入了配置数组(这仍然有点过于依赖上帝;最好是注入您需要的配置的特定键,或者更好的是,注入一个实例化的类)

在这里,插件被修改为采用配置