开发者

OO PHP where to reference singleton class?

I am going to use singleton classes to manage both DB connections and references to application settings.

It seems a little messy to have to use the following code in every method in order to access the开发者_如何学Go db class.

$db = DB::getInstance();

Is there a more efficient way of going about it?

Any advice appreciated.

Thanks


I often use the Registry pattern, where this behavior occurs as well. I always set a instance variable in the constructor of my models to point to the Registry entry;

class Registry {
    private static $_instance;
    private $_registry;

    private function __construct() {
        $_registry = array();
    }

    public static function getInstance() {
        if (!Registry::$_instance) {
            Registry::$_instance = new Registry();
        }

        return Registry::$_instance;
    }

    public function add($key, &$entry) {
        $this->_registry[$key] = &$entry;
    }

    public function &get($key) {
        return $this->_registry[$key];
    }

    public function has($key) {
        return ($this->get($key) !== null);
    }
}

Model example;

class MyModel {
    private $_db;
    public function __construct() {
        $this->_db = Registry::getInstance()->get('dbKey');
    }

    /* Every function has now access to the DAL */
}

Instantiation example;

$dal = new Db(...);
Registry::getInstance()->add('dbKey', $dal);
...
$model = new MyModel();
$model->doDbStuff();

Another approach is to always pass the reference as a parameter to each constructor.

Of course I only use this behavior when most of the methods in my model use the reference, if only a few (one or two) methods have use of the reference, I call the Registry/Singleton like you showed.


It is not messy. This is an intended behavior of Singletons. And, actually, this is just one line of code. Do you wish to make it even more compact? :)


My preferred method is to create a Base class which all the classes that need db access descend from. Base calls the singleton(s) in its constructor. All its children call their parent constructor. e.g.:

class Base {
  protected $db;

  public function __construct(){
    $this->db = DB::getInstance();
  }
}

class Achild extends Base {
  protected $var1;

  public function __construct($arg){
     parent::__construct();
     $this->var1=$arg;
  }
}


I know what you mean... hate that ::getInstance() stuff! So go and use static methods:

class DB {
    private static $db;

    public static function getInstance() {
        if(!self::$db) {
            self::$db = new DBconnector();
        }
    }

    public static function query($query) {
        return self::$db->query($query);
    }
}

Usage is much nicer:

$result = DB::query('SELECT whatever;');

And if you use PHP 5.3 you can write a __callStatic similar to this, to forward all the method calls to the object:

public static function __callStatic($method, $args) {
    call_user_func_array(array(self::$db, $method), $args);
}

And to make me happy, add an __autoloader so that you can access DB without any worries any time!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜