代码之家  ›  专栏  ›  技术社区  ›  Timo Huovinen

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

  •  4
  • Timo Huovinen  · 技术社区  · 15 年前

    当我找到php脚本或查看php框架时,我会看到一个“registry class”或“container class”,它通常使用\uu get magic方法保存变量或其他对象。

    下面是一个过于简单化的例子:

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

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

    例2:

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

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

    我使用几个类测试了container和simplecontainer,这些类将包含并重复使用大约100000次,“示例1”在本地机器上用0.75秒完成,而“示例2”用0.29秒完成。

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

    2 回复  |  直到 12 年前
        1
  •  8
  •   Jeff Puckett    9 年前

    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
    

    您的版本不依赖与容器对象的私有成员相同的类名。好吧,所以这应该很容易避免,但是要想找到一个bug是很痛苦的。安全编码意味着更少的压力。

        2
  •  4
  •   prodigitalson    15 年前

    如果没有第一步,示例2不会将对象定义为 protected private simplecontainer::objects 将是可以覆盖的公共成员,如:

    $container->className = new SomethingElse();

    推荐文章