2012-10-24 40 views
10

php 5.3+來自同一類但未實例化的靜態方法的php調用類方法

對不起,我想完整地瞭解這一點。

我知道我無法從靜態方法內部調用一個非靜態的相同類方法,而沒有將該類作爲對象實例化。

class Person 
{ 
    private $people_array; 

    function data_all_get() 
    { // touch database, return array of people 
     $this->people_array = // etc dbquery results 
    } 

    static function showPeople() 
    { // call class method 
     $people_data = $this->data_all_get(); 
     // Fatal error: Using $this when not in object context 
    } 
} // end class Person 

從SO搜索,我發現了一些有趣的方法,但想知道每種方法如何影響代碼環境。

我的問題是如下:

我可以實例化類的靜態方法內的對象,以獲得對非靜態方法

static function showPeople() 
{ // instantiate as object 
    $person = New Person(); 
    // call class method 
    $people_data = $this->data_all_get(); 
} 

Q1訪問 - 有什麼問題可以這項事業? 在我的情況下,該類沒有構造函數,所以沒有其他類方法和變量會受到實例的影響。在腳本執行期間,這個新對象會佔用內存中的一小部分空間嗎?似乎不是太糟糕了......


的另一種選擇是將「data_all_get」的方法轉換成一個靜態方法,所以它可以從靜態方法「showPeople」內部調用,即

self::showPeople() 

當其實例化爲對象時,其他方法正在使用「data_all_get」方法設置專用變量的值,以減少到數據庫的間隔(如果已設置)。我知道這可能是一個構造函數的一部分,但我從來沒有必要爲每個php腳本請求多次安裝此「Person」對象,該類主要用於組織函數和變量。

Q2 - 將「data_all_get」變成靜態方法的含義是什麼? 有沒有?如果該方法是靜態的,但它設置私有var $ people_array(不是靜態的)的值,我認爲如果對象需要在單個實例中第二次實例化,那麼var就可以被更新或覆蓋腳本請求,正確嗎?另外,因爲該屬性不是靜態的,所以該類的其他方法可以訪問它。

Q3 - 我可以多次調用靜態方法「data_all_get」而無需「破壞任何東西」(一個加載的問題IK)。

Q4 - 每次調用靜態方法時它是否只使用額外的內存?

謝謝

+0

我不明白爲什麼showPeople在這裏列出的是一個靜態函數。你上面粘貼的代碼看起來像非常標準的OO代碼,正如你所提到的,如果你可以只是實例化類,那麼沒有理由靜態運行它。我認爲想想靜態方法的最佳方式就像獨立函數一樣,封裝在類中。 (這對我來說無論如何)。從你所描述的內容來看,只需放下靜態調用,但如果你需要使用它,我認爲你上面粘貼的代碼應該沒問題(實例化類)。 – DaOgre

+1

感謝您的反饋。我使這個方法是靜態的,所以它可以從應用程序的其他區域/路由中調用,而不需要首先實例化一個對象(就像在oop世界中的包含文件)。我做了一些更多的研究和測試,目前我傾向於使成員屬性也是靜態的,而其他需要設置這些屬性的類方法是靜態的,所以這個靜態類可以調用它們。現在正在處理它... –

+0

更新:我重構並使成員屬性爲靜態,並使getter&setter函數爲靜態,以便可以通過靜態成員方法和類方法調用它們,並且它正在工作。但仍然希望您對我上面列出的4個問題有任何意見和建議,謝謝。 –

回答

11
class Person 
{ 
    private static $people_array; 

    static public function data_all_get() 
    { 
     self::$people_array = //DBStuff 
    } 

    static public function showPeople() 
    { 
     $people_data = self::data_all_get(); 
    } 
} 

短短几個音符,一些也許明顯。 1)因爲你沒有返回任何東西,所以上面的代碼將失敗。根據上面的代碼,沒有什麼不對。回答你的Q1,你所做的全部工作都是使用全局變量進行一對函數調用,並將它們封裝在一個類中。我建議不要使用它作爲實例化的類,有時候不這樣做,因爲它會使你的最終代碼變得更加可讀,並且讓人們更難以理解它們何時查看它。

如果您擔心不止一次地實例化,您可能需要查看單例設計模式,但是一般情況下,如果您打算在某個時刻實例化該類,我會重新檢查爲什麼您要「首先靜態地稱這些爲靜態。根據我的觀點,除此之外,沒有任何問題。 Q2)將data_all_get放入靜態數組的唯一含義就是它引用一個靜態屬性,這意味着如果實例化該屬性將不可訪問。另外,你失去了實例化這個類的多個版本的能力(如果這很重要),並且基本上把people_array變成了一個全局變量。這並不一定是壞事,但不知道你的其他功能在做什麼,很難說出它的含義。

Q3)多次運行它的唯一問題是:A)清除人員數組中的任何內容,以及B)多個數據庫調用。沒有看到其他代碼是怎麼回事,這個問題或多或少不可能回答。

Q4)這裏所列出的方法的內存大小可以忽略不計,不值一提。關注數據庫調用本身,以及在那裏訪問的行數

最後,這有點奇怪,因爲您現在編寫了此代碼,因爲showPeople與data_all_get完全相同。您可能想要在showPeople中編寫一些邏輯來查看$ people_array是否爲空,如果是,請運行data_all_get,如果不是,則返回people_array。這將避免額外的數據庫讀取。如果你每次都去閱讀數據庫,那麼你也可以讓data_all_get返回$ people_array,在這種情況下,這些都不需要在類中,它可以是一個函數調用,它返回它的內容在數據庫中找到。

相關問題