使用__set和__get魔术方法来实例化类


use the __set and __get magic methods to instantiate classes

我正在自动加载我的类,并希望在使用时动态实例化类。

我想要一种方法在调用类时实例化类,而不是在我的父类中有 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()

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

__get需要返回一个值。

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

是拼图的一部分。

从你所说的来看,你根本不需要__set - 除非等效属性被声明为受保护,并且你要从实例外部设置它(但你为什么要这样做)。

如 @KingCrunch 所示,可以将命名空间类引用为:

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

您可能正在寻找更多:

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

它负责类名以及实际进行的赋值(代码中缺少)。