2013-10-18 106 views
1

什麼是檢查實例變量是否從未分配的好方法?考慮下面的例子。 $this->foo爲空即可開始。如果在數據庫中找到$this->foo,則後續調用getFoo()將不會查詢數據庫。但是,如果數據庫中沒有任何內容被返回(null),所有後續調用仍然會觸發數據庫..不好。php檢查是否聲明瞭實例變量但未分配實例變量

class FooBar 
{  
    protected $foo; 
    protected $db;  

    public function getFoo() 
    { 
    if (is_null($this->foo)) { 
     $this->foo = $this->db->getFooFromDatabase(); 
    } 

    return $this->foo; 
    } 
} 
+0

我認爲你需要使用一個虛擬值而不是null ......這樣你可以區分「未設置」和「空」。 – mpen

+0

@標記我認爲你是對的。不知道是否有一個流行的價值/對象/不斷這樣做 – David

回答

1

這是一個黑客,我猜,但如何不簡單不設置它呢?然後只需檢查對象是否具有該屬性。

class FooBar 
{ 
    //REMOVED 
    //protected $foo; 
    protected $db;  

    public function getFoo() 
    { 
    if (! property_exists($this, 'foo')) { 
     $this->foo = $this->db->getFooFromDatabase(); 
    } 

    return $this->foo; 
    } 
} 
+0

'isset'也檢查它是否爲空......我不認爲這會工作。 – mpen

+1

你說得對,我相信'property_exists'就是爲此而設計的。編輯。 – SolarBear

1

沒有辦法做到保持一個單獨的「迄今分配的」布爾標誌的短缺。在大多數情況下,默認值(如在這種情況下,通常爲null)充當哨兵,我不明白爲什麼它不能在這個例子中服務。您可以讓您的查詢方法返回false找不到foo,或者您可以保持原樣並使用false作爲屬性的初始值。

我會建議第一種方法:在查詢數據庫後返回null大部分時間沒有意義,通常語義null是「未知」。由於僅僅查詢數據庫,所以即使知識是「沒有任何東西」,代碼也知道

+2

我想他是說''foo'可能會在數據庫中設置,但它被設置爲'null'。他無法區分「未設置」和「foo爲空」,因爲默認情況下foo爲空。 – mpen

+0

@Mark:然後可以用其他方式完成,使用其他常量值作爲佔位符。這可能是'false',它可以用'const UNKNOWN = false'和'protected $ foo = self :: UNKNOWN'來語義加強。 – Jon

+1

我不會使用'false'作爲未知的;我會創建一個完整的虛擬單例類,以便它擁有自己的類型。我認爲ASP.NET MVC使用他們的'DbNull'類。 – mpen