Zend框架控制器之间2模块共享变量onBootstrap(Zend Framework 2 mod

2019-08-05 08:01发布

是否有可能在Module.php建立在变量,甚至共享对象(如DB适配器)所有视图控制器使用? (Zend框架2)

例如:

class Module 
{
    public function onBootstrap(MvcEvent $e)
    {

        $moduleConfig = $e->getServiceManager()->get('Config')
    }
}

而在一个控制器,莫名其妙地访问使用:

$this->moduleConfig['db']

在上面我知道,也只是为DB适配器配置阵列,但如何将连工作?

我看到一个可以在控制器动作做到这一点:

$config = $this->getServiceLocator()->get('Config')
$dba = new DbAdapter($config['db']);

我不想这样做,每一个地方,我需要我的配置。 我如何才能让它像函数:$ this->配置? 因此,它适用于所有的行动。 更妙的是,如何做到这一点的完整模块? 我知道我会对此都错了,但在ZF1我们有合适的词汇::得到()像这样简单的事情。 我读了该文档和各种TUTS在那里,但总是有正在作出一些假设,我只是迷路。 所以,我真正想要的是:A)在全球范围内访问的配置项,B)全球可访问的数据库适配器

我只是想在我的控制器在这 - $> db或$这个 - > config->项调用。 这可能吗? 我知道我失去了一些东西完全简单。

我还做了尝试设置$这个 - >配置使用$这个 - 我的__construct> getServiceLocator() - >获取(“配置”); 但我明白,服务定位器还不可用的构建过程中。 我试着做在模块的onBootstrap设立preDispatch相似,但我似乎无法得到这些物品进入我的控制器。

仅供参考,我确实有这在我的global.php(不,它不是呆在那里,只是为例):

'db' => array(
        'driver' => 'Pdo',
        'dsn'   => 'mysql:dbname=mydb;host=localhost;',
        'username' => 'root',
        'password' => '',
        'driver_options' => array(
            PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
        ),

    ),

我能够访问和使用getServiceLocator任何行动的其他项目()。 我想这些项目是可以作为我的控制属性,如$这个 - > config->项。

我明白任何指导! 谢谢!

Answer 1:

好吧......多的答案。

1.添加配置变量,站点范围。 (以及如何在控制器访问)

这是很容易,一旦我看到它的工作。 而是取决于以下preDispatch。 在您的应用程序的根,滴在配置/自动加载的文件。 说它:things.config.local.php

在这个文件中,我们只返回与配置项的数组。

<?php
return array(
    'things' => array(
        'avalue' => 'avalue1',
        'boolvalue' => true,
        ),

);

所以,我想访问,在我的控制器。 假设你在控制器中创建一个配置属性,您可以访问这种方式。 (您安装在preDispatch财产低于它的工作)在我的系统我宁愿检索等,使得价值:

$this->config['things']['boolvalue'];

但是,你可能只是在它在这样一个动作叫:

$config = $this->getServiceLocator()->get('Config');
echo $config['things']['boolvalue'];

这是容易的实际。 不知道怎么做,有一个ini文件,但在我的情况下,它不需要和我的INI文件不能也不是什么大不了直接进入阵列。 问题1解决了我!

2.如何在控制器获得preDispatch(因为__construct不会加载配置)

我的另一个问题是,我可以在全球范围内获得访问某些对象和/或值,并有当控制器和动作被初始化加载它们。 据我了解,它不能访问服务管理器配置在控制器的__construct。

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

上面的代码将无法正常工作。 我相信,因为的ServiceManager还没有提供的控制器类的构造过程。 说得通。

虽然一对夫妇额外的步骤,我可以得到preDispatch工作,类似ZF1。 那么配置东西的作品。 除了访问全局对象,如数据库。

在控制器中添加以下方法:

protected function attachDefaultListeners()
{
    parent::attachDefaultListeners();
    $events = $this->getEventManager();
    $this->events->attach('dispatch', array($this, 'preDispatch'), 100);
    $this->events->attach('dispatch', array($this, 'postDispatch'), -100);
}

然后加入前置和后置的方法。

public function preDispatch (MvcEvent $e)
{
    // this is a db convenience class I setup in global.php
    // under the service_manager factories (will show below)
    $this->db = $this->getServiceLocator()->get('FBDb');
    // this is just standard config loaded from ServiceManager
    // set your property in your class for $config  (protected $config;)
    // then have access in entire controller
    $this->config = $this->getServiceLocator()->get('Config');
    // this comes from the things.config.local.php file
    echo "things boolvalue: " . $this->config['things']['boolvalue'];
}

public function postDispatch (MvcEvent $e)
{
    // Called after actions
}

问题2解决了! 初始化的控制器。

3.如何使用上面的ServiceManager加载一个DB对象在控制器使用

好吧,我想要的最后一件事是全球访问我的分贝。 我想它控制范围内的,所以我可以调用$这个 - > DB->使用fetchall任何地方。

在global.php首先设置服务经理。
此外,请记住,我不会离开它完全一样,因为它是我的global.php文件。 但是,它适用于现在。 这些阵列的加入在global.php返回数组:

'db' => array(
    'driver' => 'Pdo',
    'dsn'   => 'mysql:dbname=mydb;host=localhost;',
    'username' => 'root',
    'password' => '',
    'driver_options' => array(
        PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
    ),

),
'service_manager' => array(
    'factories' => array(
        'Zend\Db\Adapter\Adapter'
                => 'Zend\Db\Adapter\AdapterServiceFactory',
        'db-adapter' => function($sm) {
                $config = $sm->get('config');
                $config = $config['db'];
                $dbAdapter = new Zend\Db\Adapter\Adapter($config);
                return $dbAdapter;
             },
        'FBDb'  => function($sm) {
                $dba= $sm->get('db-adapter');
                $db = new FBDb\Db($dba);
                return $db;
             },

    ),
),

在上文中,我建立了数据库配置,然后service_manager有一些工厂,需要应用程序的其余部分时被提供。 就我而言,我想一些方便与一些我以前的ZF1代码的向后兼容性,所以我加了所谓的FBDB自定义模块。 我发现叫ZFBridge由法布里奇奥Balliano一个梦幻般的包装/桥到ZF1式-DB类。 我需要伟大的工作,你可以在这里找到: https://github.com/fballiano/zfbridge

我接过的是,修改了一点,并提出了模块。 所以FBDB对象在我的控制器作为我的数据库连接可用。 同样的,“DB-适配器”如果我想在其他地方使用它。

不管怎样,在我的控制,我的设置“保护$分贝;” 在类的开始,所以我有这个属性可用。 然后如上面的#2,我有preDispatch分配FBDB数据库对象到这个 - $>分贝。

$this->db = $this->getServiceLocator()->get('FBDb');

然后在我的操作方法,如果我想,我可以叫一个记录集或分贝值与此:

$sql = 'select * from customer where cust_nbr between ? and ?';
$rs = $this->db->fetchResults($sql, array('120400', '125250'));

或者,返回数组:

$rs = $this->db->fetchAll($sql, array('120400', '125250'));

(I加入到fetchResults到ZFBridge仅PDO \结果对象之后形成用于的foreach使用DB查询返回)。

我知道一些这是prbably糟糕的设计或“坏OOP”,但它为我工作,我喜欢它。 我个人不艾克使用纯对象的数据实体的一切,只是一些事情。 很多时候,我只是想删除一个结果集,并用它做。 :)

问题解决了。 目前。 使得ZF2更友好,现在,如果你是用来ZF1。



文章来源: Zend Framework 2 module share variables between controllers onBootstrap