【问题标题】:Access to module config in Zend Framework 2在 Zend Framework 2 中访问模块配置
【发布时间】:2012-01-21 22:27:40
【问题描述】:

如何从控制器访问我的模块配置?

【问题讨论】:

  • 我知道这个决定,但我认为在新的 ZF2 中它可以做得更优雅。因为我在我的 Module 类中定义了 getConfig 方法。

标签: php dependency-injection zend-framework2


【解决方案1】:

我真的很惊讶这是多么模糊,因为我遇到了完全相同的问题并且找不到明确的答案。有人会认为 ZF2 文档会对此有所说明。无论如何,通过反复试验,我遇到了这个非常简单的答案:

内部控制器函数:

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

Inside Module 类函数(Module.php 文件):

$config = $e->getApplication()->getServiceManager()->get('Config');

$eZend\Mvc\MvcEvent 的一个实例


一般来说,配置可以从您可以访问全局服务管理器的任何地方访问,因为配置数组已注册为名为 Config 的服务。 (注意大写的C。)

这将返回 application.config.php(全局和本地)和你的 module.config.php 的联合数组。然后,您可以根据需要访问数组元素。

尽管 OP 现在已经很老了,但我希望这可以为我节省一个小时或更长时间才能得到这个答案。

【讨论】:

  • 你从哪里($this)调用这行代码?
  • @kaziTanvirAhsan 来自控制器的一种方法,我想。
  • 是的;我能够从扩展 AbstractRestfulController 的控制器中做到这一点
  • 如果我们不知道什么是“$this”,这不是一个简单的答案。例如,我已经从一个模块中尝试过它,但它不起作用。
【解决方案2】:

您究竟想在控制器中使用模块配置做什么?是不是让 DI 容器将完全配置的对象注入到您的控制器中无法做到这一点?

例如,Rob Allen's Getting Started with Zend Framework 2 给出了将配置好的 Zend\Db\Table 实例注入控制器的示例:

return array(
'di' => array(
    'instance' => array(
        'alias' => array(
            'album' => 'Album\Controller\AlbumController',
        ),
        'Album\Controller\AlbumController' => array(
            'parameters' => array(
                'albumTable' => 'Album\Model\AlbumTable',
            ),
        ),
        'Album\Model\AlbumTable' => array(
            'parameters' => array(
                'config' => 'Zend\Db\Adapter\Mysqli',
        )),
        'Zend\Db\Adapter\Mysqli' => array(
            'parameters' => array(
                'config' => array(
                    'host' => 'localhost',
                    'username' => 'rob',
                    'password' => '123456',
                    'dbname' => 'zf2tutorial',
                ),
            ),
        ),
        ...

如果您需要在应用程序完全引导后进行额外的初始化,您可以在您的 Module 类中将一个 init 方法附​​加到引导事件。 blog post by Matthew Weier O'Phinney 给出了这个例子:

use Zend\EventManager\StaticEventManager,
Zend\Module\Manager as ModuleManager

class Module
{
    public function init(ModuleManager $manager)
    {
        $events = StaticEventManager::getInstance();
        $events->attach('bootstrap', 'bootstrap', array($this, 'doMoarInit'));
    }

    public function doMoarInit($e)
    {
        $application = $e->getParam('application');
        $modules     = $e->getParam('modules');

        $locator = $application->getLocator();
        $router  = $application->getRouter();
        $config  = $modules->getMergedConfig();

        // do something with the above!
    }
}

这些方法中的任何一种都可以解决问题吗?

【讨论】:

  • 这正是我所需要的。谢谢!
【解决方案3】:

对于Beta5,您可以在Module.php中添加这样的功能

public function init(ModuleManager $moduleManager)
{ 
    $sharedEvents = $moduleManager->getEventManager()->getSharedManager();
    $sharedEvents->attach(__NAMESPACE__, 'dispatch', function($e) {
          $config = $e->getApplication()->getConfiguration();
          $controller = $e->getTarget();
          $controller->config = $config;
    });
 }

在控制器中,你可以得到配置:

print_r($this->config); 

【讨论】:

    【解决方案4】:

    要读取仅模块配置,您的模块应该只实现 LocatorRegisteredInterface

    之前:

    namespace Application;
    
    class Module
    {
       // ...
    }
    

    之后:

    namespace Application;
    
    use Zend\ModuleManager\Feature\LocatorRegisteredInterface;
    
    class Module implements LocatorRegisteredInterface
    {
       // ...
    }
    

    该实现说 LocatorRegistrationListener 将服务定位器中的模块实例保存为 namespace\Module

    然后你可以在任何地方访问你的模块:

    class IndexController extends AbstractActionController
    {
        public function indexAction()
        {
            /** @var \Application\Module $module */
            $module = $this->getServiceLocator()->get('Application\Module');
            $moduleOnlyConfig = $module->getConfig();
    
            // ...
        }
    } 
    

    【讨论】:

      【解决方案5】:

      有一个pull request ready now 从 DI 容器中提取模块类(因此是 modules/foo/Module.php Foo\Module 类)。这有几个优点,但如果您可以访问Zend\Di\Locator,您也可以再次获取该模块实例。

      如果您的动作控制器扩展了Zend\Mvc\Controller\ActionController,那么您的控制器就是LocatorAware。这意味着,在实例化时,您的控制器会被注入知道模块的定位器。因此,您可以从控制器中的 DIC 中提取模块类。现在,当您的模块使用配置文件并将其存储在模块类实例中时,您可以创建一个 getter 以从具有定位器的任何类访问该配置数据。你可能已经有你的模块的访问器Foo\Module::getConfig()

      虽然 ZF2 正在大力开发中,也许此代码稍后会更改,但此功能目前已被 this test 覆盖,这是最相关的部分:

      $sharedInstance = $locator->instanceManager()->getSharedInstance('ListenerTestModule\Module');
      
      $this->assertInstanceOf('ListenerTestModule\Module', $sharedInstance);
      

      因此,使用 $sharedInstance 您的模块类,您可以从那里访问配置。我期待这个功能的简写很快,但这只能在 PR #786 被合并到 ZF2 主控器中后才能完成。

      【讨论】:

        【解决方案6】:

        您需要从您的模型中实现 ServiceLocatorAwareInterface。然后你可以设置 setServiceLocator() 和 getServiceLocator() 让你直接访问服务管理器。看看这个代码示例https://gist.github.com/ppeiris/7308289

        【讨论】:

        • 这是一个很好的答案,因为在任何控制器中调用 ServiceLocator 被认为是一种不好的做法。您需要通过服务(模型)调用它
        【解决方案7】:

        我创建了带有控制器插件和视图助手的模块,用于读取控制器和视图中的配置。 GitHub link __ Composer link

        通过 composer 安装

        composer require tasmaniski/zf2-config-helper
        

        在您的 config/application.config.php 文件中注册新模块“ConfigHelper

        'modules' => array(
            '...',
            'ConfigHelper'
        ),
        

        在控制器中使用它并查看文件

        echo $this->configHelp('key_from_config'); // read specific key from config 
        
        $config = $this->configHelp(); // return config object Zend\Config\Config
        echo $config->key_from_config;
        

        【讨论】:

          【解决方案8】:

          您还可以通过此 hack/tricks 在任何地方访问任何配置值

          $configReader = new ConfigReader();
          $configData = $configReader->fromFile('./config.ini');
          $config = new Config($configData, true);
          

          【讨论】:

            猜你喜欢
            • 2013-11-16
            • 1970-01-01
            • 2011-01-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-06-09
            相关资源
            最近更新 更多