我想在我的模型中檢索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內部服務器錯誤:(