2009-08-03 57 views
2

我剛剛開始進入OOP的旅程 - 目前我正試圖推出自己的MVC--純粹是爲了學習目的。我正在通過Apress PHP-Objects Patterns Practice書中的一個教程。我已經使用私有__construct/__克隆技術創建的註冊表單獨的對象:在PHP中訪問單例方法

class Registry 
{ 
    private static $instance; 
    private $values = array(); 


    private function __construct(){} 
    private function __clone(){} 

    public static function getInstance(){ 
     if(!isset(self::$instance)){ 
     self::$instance = new Registry(); 
     } 
     return self::$instance; 
     } 

    public function get($key) { 
     if (isset($this->values[$key])) { 
      return $this->values[$key]; 
      } 
     return null; 
     } 

    public function set($key, $val) { 
     $this->values[$key] = $val; 
     } 
    } 

我直接獲得此對象的實例,即:

Registry::getInstance(); 

但是,(在本教程的語法如下) - 如果我嘗試使用' - >'方法訪問公共方法 - 例如:

Registry->setVal('page',$page); 

我得到一個分析錯誤。我只能使用範圍解析運算符 - 即'::'來訪問這些方法。

我假設這是因爲對象包裝一直沒有實例 - 但我只是想驗證/與你們討論這個問題......

回答

4

Registry::getInstance()返回(實際上只)類Registry的實例。它具有與new Registry()相同的返回值,只是在整個應用程序中只能有一個實例。這些是你可能訪問方法:

// #1 
$registry = Registry::getInstance(); 
$registry->set($key, $value); 

// #2 
Registry::getInstance()->set($key, $value); 

另一個竅門:

地圖get()set()他們的魔術方法。

public function __set($key, $value) 
{ 
    return $this->set($key, $value); 
} 

public function __get($key) 
{ 
    return $this->get($key); 
} 

所以,你可以使用Registry::getInstance()->set($key, $value);Registry::getInstance()->$key = $value;

+0

這回答了我的問題...... 雖然我在這裏 - 如果一個早期的進程使用Registry :: getInstance初始化註冊表類 - 後續無關的類可以引用Registry :: set()方法而不跳過箍 - 我還是必須爲每個想要訪問它的方法的對象初始化該對象嗎? – sunwukung 2009-08-03 12:20:53

1

你需要調用SETVAL()上一個實例,而不是類本身,所以你可以這樣做:

Registry::getInstance()->set('page', $page); 
0

另一種方法是把對象創建的類,而不是必須引用它在每次使用:

public static function get($key) { 
    $instance = self::getInstance(); 
    if (isset($instance->values[$key])) { 
     return $instance->values[$key]; 
    } 
    return null; 
} 

和呼叫它只是與Registry::set('page', $page);

這樣你就可以得到一個更好的代碼,使用它,即使唱leton仍然應該被視爲一個警告標誌(如果你搜索的話,在stackoverflow上已經有很多好的線索了)。