如何在zf2中从控制器全局设置服务管理器?

时间:2014-01-07 12:53:50

标签: php zend-framework2

通常情况下,我可以通过在配置文件global.php中定义服务工厂来定义整个应用程序中的对象

我可以通过调用$this->getServiceLocator()->get('mycollection')

来获取控制器中的对象

我的代码如下: 在global.php中

service_manager' => array(
        'factories' => array(  
                  'mycollection'=> function($sm){
                        $collectionAdapter = new Collection();
                        $collectionAdapter->addItem("testvalue",'test');
                        return $collectionAdapter;
                    }

通过添加全局文件,我可以检索

//`var_dump($this->getServiceLocator()->get('mycollection')->getItem("test"));// will return testvalue`

通过申请

但我的问题是我不知道如何从控制器

完成服务的设定值

我的要求是我需要在一个控制器中设置服务并在另一个模块中检索

我在我的IndexController相册模块中尝试了以下代码

$this->getServiceLocator()->get('mycollection')->addItem('testvalue28','test8');

并在另一个模块学生IndexController中调用

//var_dump($this->getServiceLocator()->get('mycollection')->getItem("test8"));//  

我如何完成我在控制器中设置的global.php中所做的相同操作。或者更清楚地,我需要在所有模块中的一个实例中将集合值存储到整个应用程序

被修改

1)函数addItem仅根据控制器动作设置 2)是否有类似于ZEND_REGISTERY的东西,我可以在其中设置一个特定请求的值并在另一个动作中检索

//应用程序控制器定义了我需要设置不同键值对的位置

namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class IndexController extends AbstractActionController
{
    public function authenticateAction()
    {
    //----other code---------
    var_dump($this->getServiceLocator()->get('mycollection')->addItem('userauthenticationobj','userkey'));
    //$redirect=module=user  controller action =index
    return $this->redirect()->toRoute($redirect);
    }
}

在用户模块索引操作中,我需要获取在索引操作中在应用程序模块内设置的键值对。我知道这可以使用会话或数据库或cookie完成,但我想在整个应用程序中使用单例实例来实现。我不知道在oops中定义正确的术语,以便定义情况 //用户控制器

namespace User\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class IndexController extends AbstractActionController
{
    public function authenticateAction()
    {
    //----other code---------
    var_dump($this->getServiceLocator()->get('mycollection')->addItem('userkey'));
    //$redirect=module=user  controller action =index
    return $this->redirect()->toRoute($redirect);
    }
}

// IN GLOBAL.PHP我定义了

return array(
    'service_manager' => array(
        'factories' => array(
                    'mycollection'=> function($sm){
                    $collectionAdapter = new Collection();
                    $collectionAdapter->addItem("testvalue",'test');
                    return $collectionAdapter;
                }
         ),
    ),
);

//用户定义的集合引用:http://www.sitepoint.com/collection-classes-in-php/

namespace Application\Adapter;
    class Collection 
    {
        private $items = array();
        public function addItem($obj, $key = null)
        {
            if ($key == null)
            {
                $this->items[] = $obj;
            }
            else {
                if (isset($this->items[$key])) 
                {
                    throw new \Exception("Key $key already in use.");
                }
                else
                 {
                    $this->items[$key] = $obj;
                 }
            }
        }
        public function getItem($key)
        {
            if (isset($this->items[$key]))
            {
                return $this->items[$key];
            }
            else
            {
                throw new \Exception("Invalid key $key.");
            }
        }
    } 

1 个答案:

答案 0 :(得分:0)

如果您在同一个请求中(也就是说,用户没有关注链接,或者页面没有刷新),服务管理器将保持Collection的活动状态,并且您正在尝试的工作应该有效。

但是,如果您要将用户重定向到另一个控制器/操作,或者用户已经跟随链接,提交表单或导致加载新页面的任何内容,则上一页中创建的所有值将不再存在。如果您需要保留它们,则应使用会话,cookie,数据库等。

如果在操作期间未设置值,即您不需要加载控制器,但是您需要所有控制器能够在应用程序引导程序的集合中添加值,无论实际加载什么控制器,您可以在Module.php onbootstrap函数中为每个模块添加一些代码。例如,在每个模块的Module.pho中,您可以:

public function onBootstrap(MvcEvent $e) { 

    $sm = $e->getApplication ()->getServiceManager ();
    $collection = $sm->get('mycollection');
    $collection->addItem('testvalue_N','test_N');
}

然后,在每个执行的控制器/操作中,您将拥有包含所有模块添加的所有项目的集合