我想在我的模型中检索Zend_Session_Namespace的实例,但我不希望它们对Zend的实现有一个具体的依赖关系(所以我可以对它进行测试)。通过DI容器获取Zend_Session_Namespace的实例
会话实例需要在通话时传递给它的一些配置。我的其他依赖关系不可以在bootstap进程中配置。
我有一个非常基本的DI容器,从Fabien Potencier借:
class Lib_Container {
protected $services = array();
function __set($id, $service) {
$this->services[$id] = $service;
}
function __get($id) {
if (!isset($this->services[$id])) {
throw new ServiceNotRegisteredException(
"Service '$id' has not been registered"
);
}
if (is_callable($this->services[$id])) {
return $this->services[$id]($this);
}
return $this->services[$id];
}
}
我使用这个要连接我的依赖关系:
$container = new Lib_Container;
$container->session = function($c) {
return new Zend_Session_Namespace($c->sessionName);
};
...
我用我的基地内,这些依赖模型(我不希望我的模型对我的容器配置了解太多):
class Lib_Model {
protected $_container;
protected $_sessionName = 'default';
protected $_sessionInstance;
public function __construct($container) {
$this->_container = $container;
}
public function getDB() {
return $this->_container->database;
}
public function getRequest() {
return $this->_container->request;
}
public function getSession($ns = null) {
$ns = ($ns == null) ? $this->_sessionName : $ns;
if (!isset($this->_sessionInstance[$ns])) {
$this->_container->sessionName = $ns;
$this->_sessionInstance[$ns] = $this->_container->session;
}
return $this->_sessionInstance[$ns];
}
}
这使我的子类,以获取合理方便的一个会话实例:
class Model_User extends Lib_Model {
protected $_sessionName = 'user';
public function loggedIn() {
$session = $this->getSession();
return ($session && $session->loggedIn) ? true : false;
}
}
或传递会话命名空间作为参数:
$session = $this->getSession('admin');
但是,我Lib_Model::getSession()
方法相当复杂,我想,并且知道我的DI容器太多。理想的情况是想通过调用获得的Zend_Session_Namespace
一个实例:
class Lib_Model {
protected $_sessionName = 'default';
protected $_sessionFactory;
...
public function __construct($container) {
$this->_sessionFactory = $container->session;
}
...
public function getSession($ns = null) {
$ns = ($ns == null) ? $this->_sessionName : $ns;
if (!isset($this->_sessionInstance[$ns])) {
$this->_sessionInstance[$ns] = $this->_sessionFactory($ns);
}
return $this->_sessionInstance[$ns];
}
}
我很感激,如果它的服务调用(如匿名函数)我的DI容器,检查和执行它们。如果我消除这种行为,自动布线元件会崩溃?
任何想法如何才能实现$container->session('my_namespace')
返回相当于new Zend_Session_Namespace('my_namespace')
?
更新:我以为我到的东西改变我的容器的配置:
$container->session = function($c) {
$s = function($namespace) {
return new Zend_Session_Namespace($namespace);
};
return $s;
};
这样$container->session
将返回的功能。更新我的Lib_Model
类:
Lib_Model {
private $_sessionFactory;
...
public function __construct($container) {
...
$this->_sessionFactory = $container->session;
}
...
public function getSession($ns = null) {
$ns = ($ns == null) ? $this->_sessionName : $ns;
if (!isset($this->_sessionInstance[$ns]))
$this->_sessionInstance[$ns] = $this->_sessionFactory($ns);
return $this->_sessionInstance[$ns];
}
}
不幸的是这给了我一个500内部服务器错误:(