以最小的工作量创建任意对象层次结构


Creating arbitrary object hierarchies at a minimum effort?

我的Chart类实际上允许我创建简单的属性(类型为stringboolean等)以及嵌套的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();
        }
    }
}

我自己找到了解决方案。诀窍是将父属性传递给__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();
    }
}