OO PHP, где ссылаться на класс Singleton? - PullRequest
1 голос
/ 30 октября 2009

Я собираюсь использовать одноэлементные классы для управления соединениями с БД и ссылками на настройки приложения.

Кажется немного беспорядочным использование следующего кода в каждом методе для доступа к классу db.

$db = DB::getInstance();

Есть ли более эффективный способ сделать это?

Любой совет приветствуется.

Спасибо

Ответы [ 4 ]

0 голосов
/ 30 октября 2009

Я знаю, что вы имеете в виду ... ненавижу это :: getInstance () вещи! Так что иди и используй статические методы:

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);
    }
}

Использование намного приятнее:

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

И если вы используете PHP 5.3, вы можете написать __callStatic, похожий на этот, для пересылки всех вызовов метода к объекту:

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

И чтобы сделать меня счастливым, добавьте __autoloader, чтобы вы могли в любой момент получить доступ к БД без каких-либо забот!

0 голосов
/ 30 октября 2009

Мой предпочтительный метод - создать базовый класс, из которого происходят все классы, которым нужен доступ к базе данных. Base вызывает синглтон (ы) в своем конструкторе. Все его дети называют их родительским конструктором. 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;
  }
}
0 голосов
/ 30 октября 2009

Я часто использую шаблон реестра, где также происходит такое поведение. Я всегда устанавливаю переменную экземпляра в конструкторе моих моделей, чтобы указывать на запись реестра;

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);
    }
}

Пример модели;

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

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

Пример использования;

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

Другой подход - всегда передавать ссылку в качестве параметра каждому конструктору.

Конечно, я использую это поведение только тогда, когда большинство методов в моей модели используют ссылку. Если только несколько (один или два) метода используют ссылку, я вызываю Registry / Singleton, как вы показали.

0 голосов
/ 30 октября 2009

Это не грязно. Это предполагаемое поведение синглетонов. И, на самом деле, это всего лишь одна строка кода. Хотите сделать его еще более компактным? :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...