Zend Framework 2 模块在控制器之间共享变量 onBootstrap [英] Zend Framework 2 module share variables between controllers onBootstrap

查看:17
本文介绍了Zend Framework 2 模块在控制器之间共享变量 onBootstrap的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is it possible to create variables or even shared objects (like DB adapter) at in Module.php for use in all view controllers? (Zend Framework 2)

例如:

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

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

在控制器中,以某种方式访问​​使用:

And in a controller, somehow access using:

$this->moduleConfig['db']

在上面我知道这只是 db 适配器的配置数组,但它是如何工作的?

In above I know that would just be the config array for the db adapter, but how would that even work?

我看到可以在控制器操作中做到这一点:

I see that one can do this in a controller action:

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

我不想在每个需要我的配置的地方都这样做.我怎么能让它像: $this->config ??所以它可用于所有操作.更好的是,如何在整个模块中做到这一点?我知道这一切都错了,但是在 ZF1 中,我们使用 Zend_Registry::get() 来处理诸如此类的简单事情.我正在阅读文档和那里的各种嘘声,但总是有一些假设,我只是迷路了.所以我真正想要的是:A) 一个全局可访问的配置项,B) 一个全局可访问的数据库适配器

I don't want to do that every place I need my config. How could I make it something like: $this->config ?? So its available to all actions. Even better, how to do that in the entire Module? I know I am going about this all wrong, but in ZF1 we had Zend_Registry::get() for simple things like this. I am reading over the docs and all sorts of tuts out there, but always there's some assumptions being made and I just get lost. So all I really want is : A) A Globally accessible config item, B) A globally accessible db adapter

我只想在我的控制器中调用 $this->db 或 $this->config->item .这可能吗?我知道我遗漏了一些非常简单的东西.

I just want to call on $this->db or $this->config->item in my controllers. Is this possible? I know I am missing something totally simple.

我也尝试使用 $this->getServiceLocator()->get('Config'); 在我的 __construct 中设置 $this->config;但我知道在构建期间服务定位器尚不可用.我尝试通过在模块的 onBootstrap 中设置 preDispatch 来做类似的事情,但我似乎无法将这些项目放入我的控制器中.

Also I did try setting $this->config in my __construct using $this->getServiceLocator()->get('Config'); But I understand that service locator is not available yet during construct. I tried doing similar by setting up a preDispatch in the onBootstrap of the module, but I can't seem to get those items into my controllers.

仅供参考,我的 global.php 中有这个(不,它不会留在那里,只是示例):

FYI, I do have this in my global.php (and no, its not staying there, just example):

'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() 在任何操作中访问该项目和其他项目.我希望这些项目可用作我的控制器属性,如 $this->config->item.

I am able to access that and other items in any action using getServiceLocator(). I'd like those items to be available as my controller properties as in $this->config->item.

我感谢任何指导!谢谢!

I appreciate any guidance! Thanks!

推荐答案

好的...多部分回答.

Okay... multipart answer.

这很容易,一旦我看到它起作用了.但取决于下面的 preDispatch.在您的应用根目录中,在 config/autoload 中放置一个文件.称它为:things.config.local.php

This was easy, once I saw it work. But depends on the preDispatch below. In your app root, drop a file in config/autoload. Call it: things.config.local.php

在这个文件中,我们只返回一个包含配置项的数组.

In this file, we just return an array with config items.

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

);

所以我想在我的控制器中访问它.假设您在控制器中创建了一个配置属性,您可以通过这种方式访问​​它.(您在下面的 preDispatch 中设置该属性使其工作)在我的系统中,我更喜欢像这样检索该值:

So I want access to that in my controller. Assuming you create a config property in the controller, you can access it this way. (you setup that property in preDispatch below for it to work) In my system I'd prefer to retrieve that value like so:

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

但是,您可以在这样的操作中调用它:

However, you could just call upon it in an action like this:

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

其实这很容易.不确定如何使用 ini 文件执行此操作,但在我的情况下不需要它,并且我的 ini 文件直接移入数组并不是什么大问题.问题 1 为我解决了!

That was easy actually. Not sure how to do that with an ini file, but in my case its not needed and my ini files not not a big deal to move into arrays directly. Problem 1 solved for me!

我的另一个问题是我可以在全局级别访问某些对象和/或值,并在初始化控制器和操作时加载它们.据我了解,无法在控制器的 __construct 中访问服务管理器配置.

My other problem was that I could get access to some objects and/or values at a global level AND have them load when the controller and actions are initialized. As I understand it, its not possible to access service manager config in __construct of controller.

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

以上方法无效.我相信是因为在构建控制器类期间 ServiceManager 尚不可用.有道理.

The above won't work. I believe because ServiceManager isn't available yet during construct of the controller class. makes sense.

虽然有几个额外的步骤,我可以让 preDispatch 工作,类似于 ZF1.THEN 配置文件有效.以及访问全局对象,如数据库.

A couple extra steps though, and I can get preDispatch working, similar to ZF1. THEN the config stuff works. As well as access to global objects, like database.

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

In the controller add the below method:

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

然后添加 pre 和 post 方法.

Then add pre and post methods.

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解决了!初始化控制器.

Problem 2 solved! Init for controllers.

好的,我最不想要的就是全局访问我的数据库.我想要它在控制器范围内,所以我可以在任何地方调用 $this->db->fetchAll.

Okay, the last thing I wanted was access to my db globally. And I wanted it controller-wide so I can call $this->db->fetchAll anywhere.

首先在 global.php 中设置服务管理器.
另外,请记住,我不会像在我的 global.php 文件中那样完全保留它.但它现在有效.将这些数组添加到 global.php 中的返回数组:

First setup service manager in global.php.
Also, keep in mind, I won't be leaving it exactly like this as it is in my global.php file. But it works for now. Add these array's to the return array in 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;
             },

    ),
),

在上面,我设置了 db 配置,然后 service_manager 有一些工厂,它们在应用程序的其余部分需要时可用.就我而言,我希望能够方便地向后兼容我的一些旧 ZF1 代码,因此我添加了一个名为 FBDb 的自定义模块.我找到了 Fabrizio Balliano 的一个名为 ZFBridge 的出色包装器/桥接至 zf1-style-db 类.非常适合我的需求,您可以在这里找到:https://github.com/fballiano/zfbridge

In the above, I setup the db config, then service_manager has some factories, which are made available when needed in rest of app. In my case, I wanted some convenience for backwards compatibility with some of my old ZF1 code, so I added a custom module called FBDb. I found a fantastic wrapper/bridge-to-zf1-style-db class called ZFBridge by Fabrizio Balliano. Worked great for my needs, you can find here: https://github.com/fballiano/zfbridge

我接受了它,对其进行了一些修改,然后制作了一个模块.因此 FBDb 对象在我的控制器中可用作我的数据库连接.如果我想在其他地方使用它,则与db-adapter"相同.

I took that, modified it a bit, and made a module. So the FBDb object is available in my controllers as my database connection. Same with "db-adapter" if I wanted to utilize it elsewhere.

无论如何,在我的控制器中,我设置了protected $db;"在课程开始时,我可以使用该属性.然后如上面的 #2 所示,我有 preDispatch 将 FBDb 数据库对象分配给 $this->db.

Anyway, in my controller, I setup "protected $db;" at the start of the class so I have that property available. Then as shown in #2 above , I have preDispatch assigning the FBDb database object to $this->db.

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

然后在我的操作方法中,如果我愿意,我可以用这个调用记录集或数据库值:

Then in my action methods, if I want, I can call a record set or db value with this:

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

OR,对于返回的数组:

OR, for an array returned:

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

(我将 fetchResults 添加到 ZFBridge 以仅返回来自 db 查询的 PDO\Results 对象,以便稍后在 foreach 中使用.)

(I added fetchResults to ZFBridge to return only the PDO\Results object form the db query for use in foreach later.)

我知道其中一些可能是糟糕的设计或糟糕的 OOP",但它对我有用,我喜欢它.我个人不喜欢对所有事物使用基于纯对象的数据实体,只对某些事物使用.很多时候,我只想放入一个结果集并完成它.:)

I know some of this is prbably bad design or "bad OOP", but it works for me and I like it. I personally don't lke using pure object based data entities for everything, just some things. Much of the time, I just want to drop a resultset in and be done with it. :)

问题已解决.目前.如果您习惯了 ZF1,那么现在使 ZF2 更加友好.

Problems solved. For now. Makes ZF2 much more friendly now, if you are used to ZF1.

这篇关于Zend Framework 2 模块在控制器之间共享变量 onBootstrap的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆