使用 PHP 的单例模式

问题描述 投票:0回答:4

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

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 zend-framework singleton
4个回答
2
投票

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

如果您想通过连续调用来维护状态,您需要使用 $_SESSION 来跟踪您的状态。

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


0
投票

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

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

    // ...
}

0
投票

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

PHP 是一个无共享架构;每个 请求在新的进程中开始,请求结束时,就全部了 扔掉。跨请求持久化根本不可能发生——除非 你自己做缓存。您可以序列化对象并恢复它们—— 但实际上,在大多数情况下,你不会从中获得什么好处 这(并且经常遇到各种各样的问题,特别是当涉及到 到资源句柄)。

您可能想使用 Zend_cache 来实现持久化


0
投票

尽管这已经很旧了,我还是想加我的 2 美分。

Zend 创建一个在多个请求中持续存在的单例。无论 ZF 文档的解释如何,在每次请求时,整个堆栈都会重新初始化。

这就是你的问题所在。由于引导是在每个请求上完成的,因此每个请求也会重新初始化您的帮助器方法。据我所知,ZF 1.x 中的助手不能是单例。

我认为实现你想要的唯一方法是使用会话。

© www.soinside.com 2019 - 2024. All rights reserved.