Eli
Eli

Reputation: 4359

use the __set and __get magic methods to instantiate classes

I am autoloading my classes and want a way to dynamically instantiate the class when used.

Instead of having 20 class instantiations in my parent class, I want a way to instantiate a class when its being called.

for example:

$this->template->render();

will instantiate

$this->template = new Template();

I attempted this

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

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

This doesn't seem to work, but I also think I'm doing it wrong.

One issue that I can't figure out also is that my classes reside in the \System namespace. I can't seem to tack on new "\System".$name() or new \System.$name() without getting an error;

Upvotes: 3

Views: 132

Answers (3)

KingCrunch
KingCrunch

Reputation: 131881

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

Upvotes: 4

AD7six
AD7six

Reputation: 66188

__get needs to return a value. as such:

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

is one part of the puzzle.

From what you've said you don't need __set at all - unless the equivalent property is declared as protected and you're going to set it from outside the instance (but why would you do that).

As indicated by @KingCrunch, you can reference a namespaced class as:

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

Upvotes: 3

hakre
hakre

Reputation: 197722

You're probably looking more for this:

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

it takes care of the classname and that the assignment is actually made (which was missing in your code).

Upvotes: 1

Related Questions