2012-04-19 73 views
3

我自動加載我的類,並希望在使用時動態實例化類。使用__set和__get魔術方法實例化類

而不是在我的父類中有20個類實例化,我想要一個方法來實例化一個類時被調用。

例如:

$this->template->render(); 

將實例

$this->template = new Template(); 

我嘗試這個

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

public function __get($name) 
{ 
    $this->$name = new $name(); 
} 

這似乎並不工作,但我也覺得我這樣做錯誤。

我弄不清楚的一個問題是我的類位於\ System命名空間中。我似乎無法解決new "\System".$name()new \System.$name()而沒有出現錯誤;

回答

4
private $_template; 
public function __set($name, $value) 
{ 
    $this->{'_' . $name} = $value; 
} 

public function __get($name) 
{ 
    if (!$this->{'_' . $name}) { 
    $classname = '\\System\\' . ucfirst($name); 
    $this->{'_' . $name} = new $classname(); 
    } 
    return $this->{'_' . $name}; 
} 
+0

是有辦法不多自動創建屬性如何,您可以在__construct()方法創建一個屬性? – Eli 2012-04-19 21:01:22

+0

你已經想要命名你的「虛擬」屬性'template',因此命名真正的屬性並不明智。 – KingCrunch 2012-04-19 21:02:31

+1

不應該'__set()'方法設置一些東西而不是返回一些東西? – 2012-04-19 21:11:59

1

你可能期待更多這樣的:

public function __set($name, $value) 
{ 
    $this->$name = $value; 
} 

public function __get($name) 
{ 
    if (isset($this->$name)) { 
     return $this->$name; 
    } 

    $class = sprintf('\\System%s', ucfirst($name)); 
    return $this->$name = new $class();   
} 

它需要的類名的,而且轉讓實際上是由保健(這是在你的代碼丟失)。

3

__get需要返回一個值。因此:

public function __get($name) 
{ 
    $this->$name = new $name(); 
    return $this->$name; 
} 

是拼圖的一部分。

根據你所說的,你根本不需要__set - 除非等價屬性被聲明爲受保護,並且你將從實例外部設置它(但爲什麼要這麼做)。

正如@KingCrunch表示,你可以參考一個命名空間類爲:

$classname = '\\System\\' . ucfirst($name); 
$foo = new $classname; 
+0

+1 @ AD7six OOP的最佳特性..和國會10K – liyakat 2013-07-11 08:00:35

相關問題