Zend framework 使用PHP的单例模式

Zend framework 使用PHP的单例模式,zend-framework,singleton,Zend Framework,Singleton,我正在尝试创建一个动态导航类 class myApp_Helper_Breadcrum{ protected $navigationArray=array(); private static $_instance = null; public static function getInstance() { if (!isset(self::$_instance)) { self::$_instance = new self

我正在尝试创建一个动态导航类

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中为什么会出现这种情况吗?

请尝试按以下方式定义您的组件:

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
    {
         // ...
    }

    // ...
}

PHP不像Java那样运行,在Java中有JVM来维护类的状态。在Java中,您可以让一个单例完全按照您所描述的那样运行,但在PHP中,所有类都会随着对web服务器的每次后续调用而刷新。因此,在对服务器的调用期间,您的单例将保持不变,但一旦发送了响应,您就可以在下一次调用中重新开始

如果要通过连续调用来保持状态,则需要使用$\u会话来跟踪您的状态

编辑:
我上面的回答一般是关于PHP的,而不是专门针对Zend框架的。请参阅下面我的评论。

我遇到了完全相同的问题。 问题是类的持久性在请求范围内。 使用zend,您甚至可以有多个页面加载请求

PHP是一种无共享架构;每个 请求在一个新流程中启动,在请求结束时,一切都结束了 扔掉。跨请求持久化根本不可能发生——除非 你自己做缓存。您可以序列化对象并还原它们-- 但实际上,在大多数情况下,你从中得到的好处很少 这(而且经常会遇到各种各样的问题,尤其是当它出现时) 到资源句柄)


您可能想使用Zend_缓存来实现持久性

即使这已经很旧了,我还是想加上我的2美分

Zend不会创建跨多个请求持久化的单例。不管ZF文档的解释如何,在每次请求时,整个堆栈都会重新初始化

这就是你的问题所在。因为引导是在每个请求上完成的,所以每个请求也会重新初始化助手方法。据我所知,ZF1.x中的助手不能是单身汉


我认为这是你想要的实现的唯一方式,就是使用会话。

嗯,这很奇怪。当然,
\u construct
不应该是公共的,但即使按照所示进行设置,也不应该在那里调用它。你能把它改成private吗?并得到它调用的确切行(和错误)吗?我把它改成private,但没有任何错误。数组再次初始化,因此无法跟踪值,每次调用$nlinks->displayLinks()函数时,只有一个数组项。。这不是预期的输出。我认为它应该能够存储被推送的数组值。还有什么建议要看吗……好吧,我承认我还是不明白。你能将
var\u dump(123)
或类似的东西添加到
popin
方法中吗?如果我在popin中打印数组,它会打印数组值数组([0]=>Home)并在getInstance()中的var\u dump(self::$\u instance)中返回null。有人将此问题标记为-1,但我认为这还没有解决。我仍在寻求帮助,以防有人知道可能的原因。感谢您的建议,我添加了var_dump(self:$\u实例);在getInstance()中,它始终返回null…很抱歉,这是有效的()。如您所见,构造函数被调用一次,同一个实例
0
被重用。我想你没有告诉我们整个故事。我同意这是实现Singleton的标准方法,它应该可以工作,但在我的情况下它不工作。我所做的一切都提供了细节。类、引导调用和indexController中的调用。如果你需要更多细节,请告诉我。我会加起来的。好吧,我只是不相信这是正确的答案,问题是我认为PHP应该以某种方式存储后续调用之间的状态。。。但这是迄今为止对OP问题唯一合理的解释。)david,在Zendframework-bootstrap文件中,我看到$frontController=Zend_Controller_Front::getInstance();类实现表示它正在确保单例模式,并在连续调用页面时管理值。我不是专家只是一个好奇的问题。。。FrontController是如何管理值的……ZendFramework会自动处理会话间的单例持久化,这一点可能是正确的。我没有看到Zend标记,所以我从纯PHP OOP的角度回答。一般来说,单例不是解决许多问题的好方法,因为它们引入了另一个全局范围,很难调试和测试。我将编辑我的评论以反映我的假设。@user269867
在连续调用它所管理的页面时…
-您能显示这样写的片段吗?因为,事实并非如此——没有任何额外的工具(如会话),PHP中的每个HTTP请求都像是唯一的请求一样提供服务。@raina77ow:well'st place print\u r(Zend Front Controller实例);到应用程序的不同页面,我可以看到用所有需要的值填充的数组。!!你的意思是说-这是通过ZF中的会话实现的!!我的问题围绕着ZF而不是PHP…我已经说过我同意PHP的行为。问题在于ZF。请注意,这个问题是用Zendframework标记的。