2012-10-23 31 views
0

我正在嘗試創建一個動態導航類。使用PHP的單例模式

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 
    } 
} 

在自舉我下面

$nlinks=myApp_Helper_Breadcrum::getInstance(); 
Zend_Registry::set('nlinks',$nlinks); 

現在在我的控制,我呼籲如下

$nlinks= Zend_Registry::get('nlinks'); 
$nlinks->popin('Home'); 
$nlinks->displayLinks(); 

的問題是,即使這個類是單身的構造又被稱爲並再次讓我的數組初始化。我試圖實現的目標是在瀏覽網站時繼續推送導航數組中的項目。

任何想法爲什麼它是這樣的在ZF

+0

好吧,那很奇怪。當然,'__construct'不應該是公共的,但即使按照圖示設置,它也不應該在那裏被調用。你可以把它變成「private」嗎?並且在它被調用的地方得到確切的行(和錯誤)? – raina77ow

+0

我改變它爲私人,但沒有..沒有錯誤。數組被重新初始化,因此無法跟蹤值,每次我調用$ nlinks-> displayLinks()函數時,只有1個數組項。 ..這不是預期的產出。我認爲它應該能夠存儲已被推送的數組值。任何更多的建議,看看... – user269867

+0

單身人士是邪惡的 – dynamic

回答

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

按照建議做了,我添加了var_dump(self :: $ _ instance);在getInstance()和它總是返回null .... – user269867

+0

對不起,但這個工程([生活的例子](http://codepad.viper-7.com/0Klx4U))。正如你所看到的,構造函數被調用一次,同一個實例'0'被重用。我想你不會告訴我們整個故事。 – Florent

+0

我同意這是實現Singleton的標準方法,它假設可以工作,但在我的情況下它不起作用。我所做的所有事情我都提供了細節。類,引導程序調用和indexController中的調用。如果您需要更多詳細信息,請告知我。我會加起來。 – user269867

2

PHP沒有運行像Java會在哪裏,你有一個JVM,以保持你的類的狀態。在Java中,你可以讓一個singleton的行爲與你描述的完全一致,但是在PHP中,隨着每次對Web服務器的調用,所有的類都會刷新。因此,您的單身人士將在服務器的呼叫期間保持原位,但一旦發送了響應,您就會在下一次呼叫時重新開始。

如果你想通過連續的調用來維持狀態,你需要使用$ _SESSION來跟蹤你的狀態。

編輯: 我上面的答案涉及PHP的一般,而不是專門的Zend框架。看到我下面的評論。

+0

好吧,我簡直不敢相信這是正確的答案,問題在於OP認爲PHP應該以某種方式在後續調用之間存儲狀態......但這是迄今爲止OP的唯一合理解釋。 ) – raina77ow

+0

david,在Zendframework - 引導文件我看到$ frontController = Zend_Controller_Front :: getInstance();類實現表示它確保單例模式並且連續調用頁面來管理值。我不是一個專家,只是一個奇怪的問題... FrontController如何管理值... – user269867

+0

您可能是正確的,ZendFramework自動照顧在會話中持久保存單例我沒有看到Zend標記,所以我從一個純PHP OOP透視圖。一般而言,單例對於許多問題並不是一個很好的解決方案,因爲它們引入了另一個難以調試和測試的全局範圍。我會編輯我的評論以反映我的假設。 – davidethell

0

我遇到了完全相同的問題。 問題是您的類的持久性在請求範圍內。 而在zend中,你甚至可以對頁面加載有多個請求。

PHP是一個無共享體系結構;每個 請求都會在一個新進程中啓動,並且在請求結束時,全部被丟棄 。堅持跨請求根本不可能發生 - 除非你做你自己的緩存 。您可以序列化對象並將其還原 - 但實際上,在大多數情況下,您將從 中得到很少的好處(並且經常遇到各種問題,特別是在資源句柄爲 時)。

您可能需要使用Zend_Cache是​​持久性

0

即使這是老了,我想補充我的2%的。

Zend 不是創建一個單例,它持續存在多個請求。無論對ZF文檔的解釋如何,在每個請求中,整個堆棧都會重新初始化。

這是您的問題來自何處。由於引導是在每個請求上完成的,因此每個請求都會重新初始化您的幫助程序方法。據我所知,助手在ZF 1.x CAN NOT是單身人士。

我看到這個正在實現的唯一方法是你想要的是使用會話。