3

我正在自动加载我的类,并且想要一种在使用时动态实例化类的方法。

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

3 回答 3

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};
}
于 2012-04-19T20:59:10.690 回答
3

__get需要返回一个值。像这样:

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

是难题的一部分。

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

正如@KingCrunch 所指出的,您可以将命名空间类引用为:

$classname = '\\System\\' . ucfirst($name);
$foo = new $classname;
于 2012-04-19T21:05:42.993 回答
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();        
}

它负责类名并实际进行分配(您的代码中缺少该分配)。

于 2012-04-19T21:04:24.137 回答