Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

php container class: why does everyone use the more complicated method?

Tags:

php

containers

When I find scripts for php or look at php frameworks I see a "registry class" or a "container class" which often holds variables or other objects utilizing the __get magic method.

Here is a oversimplified example of what I mean:

example 1:

class container {
 private $objects;
 public function __get($class){
  if(isset($this->objects[$class])){
   return $this->objects[$class];
  }
  return $this->objects[$class] = new $class();
 }
}

the above example will have more functions to it when creating the class instead of just calling it but for my example it should be enough. "example 1" is how I mostly see it in scripts downloaded from the internet, it maintains a single class instance, now what I'm wondering is that wouldn't this example do the same thing and be more efficient:

example 2:

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

But I never see "example 2" in other peoples scripts which makes me think twice before even considering to use it.

I tested container vs simplecontainer using several classes that they would contain and re-use around 100000 times and "example 1" does it in 0.75seconds on my local machine, and "example 2" does it in 0.29seconds.

which should I use in my scripts? example 1 or example 2? and why?

like image 910
Timo Huovinen Avatar asked Dec 16 '22 21:12

Timo Huovinen


2 Answers

Because in yours I can't do this:

class container {
    private $foo = "I'm only a var";
    private $objects;
    public function __get($class){
        if(isset($this->objects[$class])){
            return $this->objects[$class];
        }
        return $this->objects[$class] = new $class();
    }
}

class simplecontainer {
    private $foo = "I'm only a var";
    public function __get($class){
        return $this->$class = new $class();
    }
}

class foo {
    public $bar = "wibble";
}

$c1 = new container();
$c2 = new simplecontainer();

$foo = $c1->foo;
$foo->bar = "Don't you forget about me!";
unset($foo);
$foo = $c1->foo;
echo $foo->bar;
// Don't you forget about me!

$foo = $c2->foo;
$foo->bar = "Don't you forget about me!";
unset($foo);   
$foo = $c2->foo;
echo $foo->bar;
// wibble

Your version relies on no class name being the same as a private member of the container object. Ok, so it should be simple to avoid, but would be a pain tracking down a bug for. Safe coding means less stress.

like image 59
Mike Avatar answered Apr 25 '23 21:04

Mike


Without first off example2 doesnt define the objects as protected or private which means that simplecontainer::objects will be a public member that can be overwritten like:

$container->className = new SomethingElse();

like image 35
prodigitalson Avatar answered Apr 25 '23 21:04

prodigitalson