我正在尝试创建一个动态导航类。
class myApp_Helper_Breadcrum{
protected $navigationArray=array();
private static $_instance = null;
public static function getInstance()
{
if (!isset(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}
private function __construct() {
$this->navigationArray = array();
}
public function popin($popInElement){
array_push($this->navigationArray,$popInElement);
}
public function displayLinks()
{
//print array
}
}
在 boostrap 中我做了以下事情
$nlinks=myApp_Helper_Breadcrum::getInstance();
Zend_Registry::set('nlinks',$nlinks);
现在在我的控制器中我调用如下
$nlinks= Zend_Registry::get('nlinks');
$nlinks->popin('Home');
$nlinks->displayLinks();
问题是,即使这个类是单例的,构造函数也会被一次又一次地调用,这使得我的数组被初始化。我想要实现的目标是在浏览网站时不断推送导航数组中的项目。
知道为什么ZF会这样吗?
PHP 不像 Java 那样运行,需要 JVM 来维护类的状态。在 Java 中,您可以让单例的行为与您所描述的完全一样,但在 PHP 中,所有类都会在每次后续调用 Web 服务器时刷新。因此,您的单例将在对服务器的调用期间保持不变,但是一旦发送响应,您就可以在下一次调用时重新开始。
如果您想通过连续调用来维护状态,您需要使用 $_SESSION 来跟踪您的状态。
编辑: 我上面的回答一般涉及 PHP,而不是专门针对 Zend Framework。请参阅下面我的评论。
尝试按如下方式定义您的组件:
class MyApp_Helper_Breadcrum
{
private static $_instance = null; // use private here
public static function getInstance()
{
if (self::$_instance === null) { // use strictly equal to null
self::$_instance = new self();
}
return self::$_instance;
}
private function __construct() // use private here
{
// ...
}
// ...
}
我遇到了完全相同的问题。 问题在于您的类的持久性在请求范围内。 使用 zend,您甚至可以有多个页面加载请求。
PHP 是一个无共享架构;每个 请求在新的进程中开始,请求结束时,就全部了 扔掉。跨请求持久化根本不可能发生——除非 你自己做缓存。您可以序列化对象并恢复它们—— 但实际上,在大多数情况下,你不会从中获得什么好处 这(并且经常遇到各种各样的问题,特别是当涉及到 到资源句柄)。
您可能想使用 Zend_cache 来实现持久化
尽管这已经很旧了,我还是想加我的 2 美分。
Zend 不 创建一个在多个请求中持续存在的单例。无论 ZF 文档的解释如何,在每次请求时,整个堆栈都会重新初始化。
这就是你的问题所在。由于引导是在每个请求上完成的,因此每个请求也会重新初始化您的帮助器方法。据我所知,ZF 1.x 中的助手不能是单例。
我认为实现你想要的唯一方法是使用会话。