2012-01-08 58 views
1

Chart類實際上允許我創建簡單的屬性(string型,boolean等等),以及嵌套object性能調用魔術__call方法是這樣的:以最小的努力創建任意對象層次結構?

$chart = new Chart(); 
$chart->simple = 'Hello'; 
$chart->newComplex(); 

var_dump($chart); 

輸出:

object(Chart)[1] 
    public 'simple' => string 'Hello' (length=5) 
    public 'complex' => 
    object(stdClass)[2] 

我想添加能力來創建嵌套object屬性作爲其他屬性的子女(不是圖表本身的子女)這樣的:

$chart->newComplex2($chart->newComplex1()); 

問題是:如何使用$args參數和修改__call()做到這一點?

class Chart 
{ 

    public function __call($name, $args) 
    { 

     $type = substr($name, 0, 3); 
     $field = lcfirst(substr($name, strlen($type))); 

     switch($type) 
     { 
      case 'get': return isset($this->$field) ? $this->$field : null; 
      case 'new': return $this->$field = new stdClass(); 
     } 

    } 

} 
+0

作爲一個建議,首先提供您正在尋找的功能並接受'$ args'數組或從'func_get_args'創建它的函數的非魔術函數代碼。您稍後可以繼續添加魔術界面。在你的代碼示例中,'$ args [0]'是你想知道的第一個參數。 – hakre 2012-01-08 11:04:09

+1

您不應該混合協作者和創作者圖。你的對象應該有單一的責任。允許他們創建對象是一項責任。將其分解爲工廠和生成器模式。 – Gordon 2012-01-08 11:28:17

+0

@戈登感謝您的提示。該圖表是一個簡單的數據容器對象。實際數據(即圖表系列)是在別處創建的,並在構建器(模式)類中與圖表合併。所以我認爲我們有單一的責任模式受到尊重。 – gremo 2012-01-08 11:47:08

回答

0

我自己找到解決方案。訣竅是將父項屬性傳遞給__call。這裏是代碼:

public function __call($name, $args) 
{ 

    $type = substr($name, 0, 3); 
    $field = lcfirst(substr($name, strlen($type))); 

    switch($type) 
    { 
     case 'get': 
      return isset($this->$field) ? $this->$field : null; 
     case 'new': 
      return (isset($args[0]) ? $args[0]->$field = new stdClass() 
       : $this->$field = new stdClass()); 
     default: return $this->$name(); 
    } 

}