PHP中的注册表或单例模式?

时间:2010-01-20 14:20:13

标签: php registry singleton

我现在正在使用PHP类和对象。在这个问题中,字段和方法的名称只是为了让你了解我在说什么。

它与使用单例和注册表设计模式有关。

现在假设我需要访问数据库对象,缓存对象,核心设置对象,几乎所有其他类中的Session对象,我需要访问这些对象。所以我会使用注册表将所有这4个对象存储到1个注册表类对象中。然后我可以将easiyl传递给我的1个对象到需要访问这些对象的任何其他对象。所以这听起来很棒,但是如果我有一些不需要所有4个对象的类,那么如果我只需要访问我的其他一些类中的Database对象或Session对象呢?对于性能,最好只在这些其他对象中使用单例,还是继续使用我的注册表?

我不太清楚PHP中的对象如何工作以了解是否会有任何类型的性能增益(更少的内存使用量,CPU使用率,加载时间)。

所以任何有这方面经验的人都可以告诉我,如果使用其中任何一个获得任何收益,我现在处于以太流行的阶段,而不会影响生产时间或任何事情。如果我能够,我想用最好的方法。

3 个答案:

答案 0 :(得分:4)

您可以实现延迟加载以仅加载您真正需要的对象:

class Registry
{
    private static $database = null;

    private static function connectDatabase($key)
    {
        [... do connection stuff ...]
    }

    public static function getDatabase($key)
    {
        if (Registry::$database == null)
        {
            Registry::connectDatabase($key);
        }
        return Registry::$database;
    }
}

注册数据库连接参数的代码留给读者练习。

答案 1 :(得分:3)

这取决于您的申请。如果你仍然需要4个类中的3个,那么使用注册表比仅仅因为你不需要第四个来独立处理3更理想。懒惰地加载类是减少内存占用的一种方法,但是你需要指示注册表何时创建对象,这与处理单例没有太大的不同。或者,您可以创建一个n参数构造函数或使用数组来指示您的注册表在构造期间实例化哪些类。

class Registry {
    public $class1;
    public $class2;

    function __construct($uses) {
        foreach($uses as $class) {
            $this->{$class} = new {$class}();
        }
    }

}

然后通过指定要实例化的类来实例化您的注册表。

$reg = new Registry(array('class1'));

您显然希望构造函数能够处理零参数,以便在默认情况下实例化所有类。

答案 2 :(得分:1)

也许这是正确的Singleton-Registry模式。 OFC,你可以实现不同的东西,SplFixedArray,ArrayAccess接口等。此外,添加破坏和破坏内部对象以确保不会发生泄漏也是不错的。

class oRegistry{
   private static $instance = null;

   private $storage = array();

   private function __construct(){}

   private function __clone(){}

   public static function getInstance(){
      if( self::$instance === null ){
         self::$instance = new self();
      }
      return self::$instance;
   }

   public function attach($name, $o) {
      if( true === isset($this->storage[$name]) ) {
          throw new Exception('The instance with name '.$name.' already exists in registry.');
      }
      if( !empty( $name ) ) {
          $this->storage[ $name ] = $o;
      }
   }

   public function detach( $name ){
       if( isset( $this->storage[ $name ] ) ) {
           $this->storage[ $name ] = null;
           unset( $this->storage[ $name ] );
       }
   }

   public function get( $name ){
       if( false === isset( $this->storage[$name] ) ) {
           throw new Exception('Invalid instance requested');
       }
       return $this->storage[ $name ];
   }
}

// usage example
$storage = oRegistry::getInstance();
$obj = new stdClass;
$obj2 = new stdClass;
$obj->test1 = 'test';
$obj2->test2 = 't2';

$storage->attach( 'test1', $obj );
$storage->attach( 'test2', $obj2 );

$got = $storage->get( 'test2' );
var_dump($got); // object(stdClass)#3 (1) { ["test2"]=> string(2) "t2" }

$storage->detach( 'test2' );
$got = $storage->get( 'test2' );
var_dump($got); // bool(false)