php容器类:为什么每个人都使用更复杂的方法?

时间:2010-09-15 07:29:56

标签: php containers

当我找到php的脚本或查看php框架时,我看到一个“注册表类”或“容器类”,它通常使用__get魔术方法保存变量或其他对象。

以下是我的意思的简化示例:

示例1:

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

上面的例子在创建类时会有更多的函数而不是只调用它,但对于我的例子来说它应该足够了。 “示例1”是我在互联网上下载的脚本中大多看到它的方式,它维护着一个单独的类实例,现在我想知道的是,这个例子不会做同样的事情并且效率更高:

示例2:

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

但我从来没有在其他人的剧本中看到“例2”,这让我在考虑使用它之前会三思而行。

我使用它们将包含的几个类来测试容器与simplecontainer并重复使用大约100000次,“示例1”在我的本地计算机上以0.75秒进行测试,“示例2”在0.29秒内完成。

我应该在我的脚本中使用哪个?例1或例2?为什么?

2 个答案:

答案 0 :(得分:8)

因为在你的我不能这样做:

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

您的版本依赖于没有类名与容器对象的私有成员相同。好的,所以应该很容易避免,但是追踪一个错误的痛苦。安全编码意味着更少的压力。

答案 1 :(得分:4)

如果没有首先关闭example2,则不会将对象定义为protectedprivate,这意味着simplecontainer::objects将成为可以覆盖的公共成员:

$container->className = new SomethingElse();