PHP — как cоединяться с Mongo по требованию (отложенно)?

Модуль для работы с Mongo, входящий в комплекс поставки PHP предоставляет возможность соединяться с сервером не сразу — позволяя выбрать базу и коллекцию без установки соединения. Для этого есть вот такая конструкция:

$mongo = new \Mongo (MONGO_SERVER, array ("connect" => false));

Однако для того, чтобы выполнить любое действие с данными необходимо прежде вызвать $mongo->connect ().

В связи с чем возник вопрос — быть может уже есть готовое решение, некий слой для работы с Mongo наподобие Zend_Db или Rediska, где это уже реализовано?

Соединяться каждый раз — бессмысленно, изобретать велосипед — тоже не хочется, обратился к коллективному разуму :-)
  • Вопрос задан
  • 2897 просмотров
Пригласить эксперта
Ответы на вопрос 6
sedictor
@sedictor
class lazyLoad_mongo {
    private $loaded = false;
    private $mongo;
    public function init() {
        $this->mongo = new Mongo(MONGO_SERVER, array ("connect" => false));
        $this->loaded = true;
    }
    public function __call($name, array $arguments) {
        if (!$this->loaded) {
            $this->init();
        }
        return call_user_func_array(array($this->mongo, $name), $arguments);
    }
    public function __callStatic($name, array $arguments) {
        $this->__call($name, $arguments);
    }
    public function __get($name) {
        if (!$this->loaded) {
            $this->init();
        }
        return $this->mongo->$name;
    }
    public function __set($name, $value) {
        if (!$this->loaded) {
            $this->init();
        }
        return $this->mongo->$name = $value;
    }
    public function __isset($name) {
        if (!$this->loaded) {
            $this->init();
        }
        return isset($this->mongo->$name);
    }
    public function __unset($name) {
        if (!$this->loaded) {
            $this->init();
        }
        return unset($this->mongo->$name);
    }
}
Ответ написан
Комментировать
Под Zend пока вроде кроме бекенда для кеша нету ничего.
Ответ написан
Комментировать
@Psih
Веб разработчик, совладелец Areto Development
Сделайте Lazy Load.

Общий паттерн таков
function makeRequest()
{
    if (!$this->isConnected()) {
       $this->connect();
    }
    parent::makeQuery();
}


И будет вам отложеное соединение. Я так с MySQL работаю. Детали реализации на вашей совести :)
Ответ написан
Комментировать
sedictor
@sedictor
Немножно переписал:
<?php
class Mongo_LazyLoad {
    private $loaded = false;
    private $mongo;
    private $args;

    public function __construct() {
        $this->args = func_get_args();
    }
    private function init() {
        if (!$this->loaded) {
            $t = create_function(null, 'new Mongo('. implode(',', $this->args) .');');
            $this->mongo = $t();
            $this->loaded = true;
        }
    }
    public function __call($name, array $arguments) {
        $this->init();
        return call_user_func_array(array($this->mongo, $name), $arguments);
    }
    public static function __callStatic($name, array $arguments) {
        $this->__call($name, $arguments);
    }
    public function __get($name) {
        $this->init();
        return $this->mongo->$name;
    }
    public function __set($name, $value) {
        $this->init();
        return $this->mongo->$name = $value;
    }
    public function __isset($name) {
        $this->init();
        return isset($this->mongo->$name);
    }
    public function __unset($name) {
        $this->init();
        unset($this->mongo->$name);
    }
}


И остается заменить new Mongo на new Mongo_LazyLoad.
Этот способ больше подходит для того, чтобы в уже существующем проекте внести минимум изменений
Ответ написан
casey
@casey Автор вопроса
В итоге я пришел вот к такому полу решению:

	public static function getMongoDb ()
	{
		static $mongodb, $mongo;

		if ($mongodb === null) {
			$mongo = new \Mongo (MONGO_SERVER);
			$mongodb = $mongo->selectDB (MONGO_DATABASE);
		}

		return $mongodb;
	}


Да, при выборе коллекции по прежнему выполняется соединение с mongo, однако если нигде на странице Mongo не используется — объекты для работы с ним так и не будут созданы.
Ответ написан
Комментировать
Плотно не работал, не знаю есть ли именно то, что нужно, но обвязка для Монго есть у Doctrine
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы