2012-04-19 7 views
3

私はクラスをオートロードしていて、クラスを動的にインスタンス化する必要があります。__setと__getのマジックメソッドを使ってクラスをインスタンス化する

親クラスに20個のクラスインスタンシエーションがあるのではなく、呼び出されるときにクラスをインスタンス化する方法が必要です。例えば

$this->template->render(); 

が、私はこれが動作するようには思えませんが、私も、私はそれをやっていると思います。この

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

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

を試みた

$this->template = new Template(); 

をインスタンス化します違う。

私が理解できない1つの問題は、クラスが\ 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

+0

あなたは既に "仮想"プロパティに 'template'という名前をつけたいので、実際のものと同じものを同じ名前にするのは賢明ではありません。 – KingCrunch

+1

'__set()'メソッドが何かを返すのではなく何かを設定するべきではありませんか? –

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; 
} 

はパズルの一部です。

同等のプロパティがprotectedと宣言されておらず、インスタンス外から設定しようとしていない限り(しかし、なぜそうするのでしょうか?)__setは必要ありません。 @KingCrunchによって示されるように

、あなたはとして名前空間、クラスを参照することができます。

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

+1 @ AD7six OOPの優れた機能と10Kの会議 – liyakat

関連する問題