当我找到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?为什么?
答案 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,则不会将对象定义为protected
或private
,这意味着simplecontainer::objects
将成为可以覆盖的公共成员:
$container->className = new SomethingElse();