Модераторы: skyboy, MoLeX, Aliance, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> class DataBase 
:(
    Опции темы
Zorak
Дата 17.3.2013, 19:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 720
Регистрация: 13.11.2007

Репутация: нет
Всего: 3



Здраствуйте дамы и господа. У меня вопрос чисто теоретический.... пока
Написал класс, который отвечает за работу с базой данных на страницах моего сайта.
Вот некоторые методы класса:
1. __construct() - обеспечивает соединение с базой данных
2. __destruct() - обеспечивает закрытие существующего соеднения с базой данных
3. методы select(), insert(), update(), delete() - тут и так все понятно.

За иронией судьбы (так сказать)  я подключаю этот класс на каждой странице и в некоторых классах, где он мне требуется. Естессно при создании обьекта класса происходит подключение к базе данных, далее браузеру передается сгенерированная страница по коду, ну и в конце уничтожается обьект класса, в следствии чего и разрывается соединение с базой данных. И таким макаром происходит на каждой странице.
Проблема в том, что я некоторым чутьем чуствую что гдето промахнулся, а в друг потом напишу несколько страниц, где будут пересекатся разные классы и обьект класса DataBase создастся два раза а того более хуже больше чем два... 
И так, вопроса два:
1. Чем это чревато?
2. как это исправить ? (хотябы куда и под каким углом смотреть).

Не хочется потом переписывать фиг знает что и сколько...

Спасибо!


--------------------
Знание - сила. А сила есть, ума не надо...
Занимаюсь интернет бизнесом и ищу новых партнеров. Кому интересно - обращайтесь в ЛС, скайп или мыло.
PM MAIL ICQ   Вверх
Gold Dragon
Дата 18.3.2013, 07:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 2
Всего: 71



ну  для класса базы данных тебе нужно воспользоваться шаблоном проектирования Singleton. Т.е. Объект создаётся всего один раз.. Вот примерная структура

Код

class GDDatabase
{
    /** @var string - хост */
    private $_db_host;

    /** @var string - пользователь */
    private $_db_user;

    /** @var string - пароль */
    private $_db_password;

    /** @var string - имя БД */
    private $_db_name;

    /** @var string - порт */
    private $_db_port;

    /** @var string - сокет */
    private $_db_socket;

    /** @var int - флаг отладки */
    private $_db_debug;

    /** @var int - флаг кэширования */
    private $_db_caching;

    /** @var string - префикс для таблиц */
    private $_db_prefix;

    /** @var string - путь до файлов кэширования */
    private $_db_cache_dir;

    /** @var int - время кэширования */
    private $_db_cache_time;

    /** @var null|object - интерфейс */
    protected static $_resource = null;

    /** @var \mysqli - MySQLi object */
    protected $db_resource;

    /** @var \mysqli_stmt - MySQLi_STMT object */
    protected $stmp;

    /***************************************************************************
     * Magic methods
    /***************************************************************************/

    /**
     * Конструктор
     * Защищаем от создания через new
     */
    private function __construct()
    {
        // Сохранение основных настроек
        // т.е. достаём из конфигурации настройки для подключения к БД и сохраняем их

        $this->_db_host = JCore::getCfg('host');

        $this->_db_user = JCore::getCfg('user');

        $this->_db_password = JCore::getCfg('password');

        $this->_db_name = JCore::getCfg('db');

        $this->_db_port = JCore::getCfg('port');

        $this->_db_socket = JCore::getCfg('socket');

        $this->_db_debug = JCore::getCfg('debug');

        $this->_db_caching = JCore::getCfg('caching');

        $this->_db_prefix = JCore::getCfg('dbprefix');

        $this->_db_cache_dir = JCore::getCfg('cachepath');

        $this->_db_cache_time = JCore::getCfg('cachetime');

        // Проверка существует ли вообще функция подключения
        if (!function_exists('mysqli_connect')) {
            throw new Exception(_EXCEP_MYSQLI_MODULE_NOT);
        }

        // Временно отключаем вывод ошибок
        $_error = error_reporting();
        error_reporting(0);

        // Создаём объект базы
        $this->db_resource = new mysqli(
            $this->_db_host,
            $this->_db_user,
            $this->_db_password,
            $this->_db_name,
            $this->_db_port,
            $this->_db_socket);

        if ($this->db_resource->connect_error) {
            throw new Exception(_EXCEP_ERROR_CONNECT_DB);
        }

        // Возвращаем состояние вывода ошибок
        error_reporting($_error);

        // Устанавливаем кодировку
        if (!$this->db_resource->set_charset('utf8')) {
            throw new Exception(sprintf(_EXCEP_ERROR_LOADING_CHARACTER_SET, $this->db_resource->character_set_name()));
        }

        // записываем логи запросов
        if ($this->_db_debug) {
            $this->db_resource->query('set profiling=1');
            $this->db_resource->query('set profiling_history_size=100');
        }
    }

    /**
     * Защищаем от создания через клонирование
     */
    private function __clone()
    {
    }

    /**
     * Защищаем от создание через unserialize
     */
    private function __wakeup()
    {
    }

    /**
     * @static Подключение класса
     *
     * @return object
     */
    public static function Init()
    {
        if (!is_object(self::$_resource)) {
            $class_name = __CLASS__;
            self::$_resource = new $class_name;
        }

        return self::$_resource;
    }

}


использовать можно так
Код

$_db = GDDatabase::Init();

Т.е. объект создаётся один раз, а все остальные подключения просто возвращают то что уже создано

ну  и дальше твои методы

Код

$_db->select .....
$_db->insert .....


или  сразу
Код

GDDatabase::Init()->select ....
GDDatabase::Init()->insert ....




ps
если вдруг что, то вот мой класс-обёртка  smile 
https://code.google.com/p/gddatabase/



--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
Zorak
Дата 18.3.2013, 09:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 720
Регистрация: 13.11.2007

Репутация: нет
Всего: 3



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


--------------------
Знание - сила. А сила есть, ума не надо...
Занимаюсь интернет бизнесом и ищу новых партнеров. Кому интересно - обращайтесь в ЛС, скайп или мыло.
PM MAIL ICQ   Вверх
ksnk
Дата 18.3.2013, 09:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 14
Всего: 386



Zorak, Мне отчего-то нравятся функции драйвера базы данных, которые возвращают не рессурсы, а данные.
Интерфейс получается, кроме служебных конструкторов-деструкторов еще и 
  • insert - возвращает количество вставленных строк
  • update - количество измененных строк.
  • select - возвращает массив массивов строк
  • selectCell - одно значение
  • selectCol - столбец - массив значений
  • selectRow - строка
Так получится менее затратно переходить на новый драйвер базы данных. с mysql, например на mysqli.

Это сообщение отредактировал(а) ksnk - 18.3.2013, 09:40


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Gold Dragon
Дата 18.3.2013, 10:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 2
Всего: 71



ksnk, однозначно ! А иначе для чего нужна обёртка  smile 

а ещё вот какие:
  • selectAll - получить все данные указав только таблицу
  • getCacheSql - ну это запрос к базе, но при использовании кэширования
  • getQueryInfo - получение дополнительной информации о запросе (количество строк, затронутых последним запросом, ID предыдущей
операцией INSERT, число строк в результате запроса, число полей в заданном выражении, ошибка последнего запроса и т.п.)

соответственно ещё 
  • getError
  • getErrno

ЗЫ
у меня в классе это всё реализовано. Да и используются подготовленные данные, так что нет смысла что-то экранировать и бояться  smile 


Это сообщение отредактировал(а) Gold Dragon - 18.3.2013, 10:09


--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
Sanchezzz
Дата 18.3.2013, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1670
Регистрация: 19.11.2006
Где: Voronezh

Репутация: 1
Всего: 60



А я сижу делаю обертку вокруг PDO для своего микро фреймворка
Поделюсь с задумкой а может для кого то идеями.

Есть класс db - это коллекция синглитон адаптеров, которые работают с разными СУБД, NOSQL
С какой базой данной работать определяется конфигом в виде массива. 

db::make() - загрузка настройки по умолчанию, db::make('mongo') загрузка указанной настройки.

dbPdo Обертка над PDO
dbMongo Обердка над монго. 

Работа с БД происходит точно также как и с обычным PDO за  исключением того что все методы можно вызвать цепочкой, меня жутко бесило это  в обычном PDO что это нельзя было это сделать.
$db = db::make();
$db->cache($duration)->prepare ... работа с кэшем, кэш также определяется в конфиге к БД, как и профайлер, логер.

$db->prepare($sql)->execute(array(':id',1)) 
->fetchAll()  // результат все
->fetch()     // первоя строка + курсор в цикде.
->fetchCulumn($column_name) // результат указанный столбец
->asModel()  // результат в виде AR модели или ее подобие (допиливаю последнее время)

$db->prepare($sql)
->bindValue 
->bindParam 
->execute() 
->fetchAll

Эмуляция плейхостов нужна для логера и дебагера.

$db->saveModel($this_class); // сохранить указанную AR модель под текущую БД. Под каждую БД приходится писать свои костыли что бы сохранить модель.
// Модель нечего нечего не знает о базе. 
// Модель спроектирована уже с необходимой структурой и связями.

$db->query($prepare,$execute,$debug=false); // результат INSERT UPADETE SELECT DELETE
$db->insert($table, $arraySet);
$db->update($table, $arraySet);




--------------------
Понравился ответ "+" по репе, не забываем закрывать тему, заказы в LS.
PM MAIL Skype GTalk   Вверх
Fortop
Дата 18.3.2013, 14:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

Репутация: 3
Всего: 42



Цитата(Gold Dragon @  18.3.2013,  07:39 Найти цитируемый пост)
ну  для класса базы данных тебе нужно воспользоваться шаблоном проектирования Singleton.

Разве?

А я думал что он нужен для подключения/адаптера, и то не всегда smile


--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
Gold Dragon
Дата 18.3.2013, 14:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 2
Всего: 71



Цитата(Fortop @  18.3.2013,  15:48 Найти цитируемый пост)
А я думал что он нужен для подключения/адаптера, и то не всегда 
а по понятнее?



--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
Fortop
Дата 18.3.2013, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

Репутация: 3
Всего: 42



По понятнее?

Избежать множества запросов синглтоном нельзя.
Но избежать множества открытий/закрытий соединения - можно.

Вся привычка делать класс работы с БД синглтоном базируется как раз на этой логике.
А раз так... то делаем синглтоном класс подключения/адаптера и используем его в своих обертках.

Код

// one.php
$db = new SuperWrapper(Connection::getInstance());
$db->query(......)

// two.php
$somewhereElse = new DuperWrapper(Connection::getInstance());





--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
baldina
Дата 18.3.2013, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 2
Всего: 101



Цитата(Fortop @  18.3.2013,  16:42 Найти цитируемый пост)
А раз так... то делаем синглтоном класс подключения/адаптера и используем его в своих обертках.

и в чем разница/выигрыш? 

Это сообщение отредактировал(а) baldina - 18.3.2013, 17:32
PM MAIL   Вверх
Fortop
Дата 18.3.2013, 17:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

Репутация: 3
Всего: 42



Цитата(baldina @  18.3.2013,  17:32 Найти цитируемый пост)
и в чем разница/выигрыш? 

Разница в архитектуре.

А вот выигрыш - вопрос спорный smile
Несколько более гибкое приложение, при условии развитого DBAL


--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
baldina
Дата 18.3.2013, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 2
Всего: 101



Цитата(Fortop @  18.3.2013,  17:45 Найти цитируемый пост)
Несколько более гибкое приложение

а если потребуется еще одно соединение?

Добавлено через 7 минут и 7 секунд
синглтон - не архитектура, а индивидуальное, редко полезное решение.
любая архитектура на его основе плохо масштабируется.

хорошая архитектура (в частности) - это когда есть согласованная структура приложения и его частей, каждая из которых отвечает за своё. тогда не понадобятся синглтоны, а повсеместные $db = new myDb() или $db = myDb::getInstance() превратятся в $app->getDb()
PM MAIL   Вверх
Fortop
Дата 18.3.2013, 22:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

Репутация: 3
Всего: 42



Цитата(baldina @  18.3.2013,  17:51 Найти цитируемый пост)
а если потребуется еще одно соединение?

Модифицируем до пула.
Или низводим с уровня синглтона соединения вообще и используем Registry для их хранения


--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
baldina
Дата 18.3.2013, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 2
Всего: 101



Цитата(Fortop @  18.3.2013,  22:14 Найти цитируемый пост)
Модифицируем до пула.

массив-синглтон? массив синглтонов? масло масляное
Цитата(Fortop @  18.3.2013,  22:14 Найти цитируемый пост)
используем Registry

который тоже синглтон?

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

 smile 
PM MAIL   Вверх
Fortop
Дата 19.3.2013, 02:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

Репутация: 3
Всего: 42



Цитата(baldina @  18.3.2013,  23:11 Найти цитируемый пост)
массив-синглтон? массив синглтонов? масло масляное

А кроме личных предпочтений к ношению розовых бикини аргументация будет?  smile 

Цитата(baldina @  18.3.2013,  23:11 Найти цитируемый пост)
потом обнаруживаются проблемы с последовательностью их инициализации

С последовательностью инициализации кого?
Соединений с БД?  smile 



--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Базы Данных | Следующая тема »


 




[ Время генерации скрипта: 0.0683 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.