2014-06-12 273 views
0

我試圖訪問一個靜態方法全局變量,但我正在逐漸的致命錯誤:訪問全局變量

Fatal error: Call to a member function prepare() on a non-object

意味着我的靜態變量不能保持全局變量,但本標準適用於常規方法(無靜態)。

class Payment_Handler { 


    private static $dbh; 


    function __construct() { 
     global $dbh; 

     self::$dbh = $dbh; 
    } 



    /** 
    * Verify Secret Key 
    * 
    * @param string $secret_key 
    * @return boolean 
    */ 
    static function verify_secret($secret_key) { 
     // Do the stuff with self::$dbh 
     $query = "............"; 
     $stmt = self::$dbh->prepare($query); 
    } 
} // End Class 

我也嘗試過谷歌,但沒有運氣。請告訴我我做了什麼錯誤,爲什麼它不能通過靜態變量訪問?

+0

你是混合構造函數中的靜態方法讓你的函數的非靜態和與對象實例調用該方法的東西'$ obj-> verify_secret( )'這樣,在對象實例化屬性通過'__construct'設置 –

回答

1

使用全局變量是ALLWAYS a 壞主意,使用靜態變量通常是一個壞主意。

你可以給通過構造的$胸徑對象,以避免全局:

class Payment_Handler { 
    private $dbh; 

    public function __construct($dbh){ 
     $this->dbh = $dbh; 
    } 

    public function verify_secret($secret_key) { 
     $query = "............"; 
     $stmt = $this->dbh->prepare($query); 
    } 
} 

甚至更​​好,使用某種依賴注入的:

class Payment_Handler { 
    private $dbh; 

    public function __construct(){} 

    public function setConnector($dbh){ 
     $this->dbh = $dbh; 
    } 

    public function verify_secret($secret_key) { 
     $query = "............"; 
     $stmt = $this->dbh->prepare($query); 
    } 
}  

爲什麼globals不好?

  • 安全問題。你的變量(數據庫更糟糕)可以從任何地方訪問
  • 狀態是不受控制的。其他代碼部分可以在您不知道的情況下更改您的變量
  • 測試。嘲笑全球的東西是非常困難的

爲什麼靜態不好?

  • 測試。嘲笑全球化的東西是非常困難的

這些「好」樣品有沒有缺點?

沒有,因爲PHP在內部使用引用的地方,你不會浪費任何內存,性能不會因爲這幾行額外的代碼而下降。

(還有其他原因,他們的這個整本書)

+0

以及我如何啓動**依賴注入?** –

+0

在您調用構造函數後立即在主代碼中調用setConnector方法。總是很高興有一個代碼的中心部分,所有這些類被初始化和注入propery。 – ToBe

+0

對不起,我錯誤地留下了一個'static'。這些樣本不是靜態的。這可能解釋你的問題。 – ToBe

2

如果您從未實例化Payment_Handler對象,則確實是NULL。我會寫一個包裝函數,而不是直接使用self::$dbh

class Payment_Handler { 
    private static $dbh; 
    function __construct() { 
     global $dbh; 
     self::$dbh = $dbh; 
    } 
    static function getDBH(){ 
     if(is_nul(self::$dbh)) self::$dbh = $GLOBALS['dbh']; 
     return self::$dbh; 
    } 
    static function verify_secret($secret_key) { 
     $query = "............"; 
     $stmt = self::getDBH()->prepare($query); 
    } 
} 

...或移動從靜態方法了,並注入在情況合適的要求。

+0

非常感謝你,這是我想知道的。 –

+0

工作解決方案,但請注意這個答案中的最後一句話!另外請注意我的答案,它詳細闡述了這一點。 – ToBe

+0

@ToBe是的,當我搜索解決方案時,我得到了這些點。但只是想知道方式。 –