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

Поиск:

Закрытая темаСоздание новой темы Создание опроса
> пара вопросов по PDO, pdo синглтон, и различия конструкторов 
:(
    Опции темы
ST_Falcon
  Дата 18.4.2008, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 330
Регистрация: 14.11.2003
Где: Львов

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



1. для того чтобы использовать pdo как синглтон класс обязательно нужно обертку писать или я просто плохо документацию читал?
2. заметил различия в аргументах конструктора для mysql и pgsql. с чем это связано?

а пока что использую вот такой фантик. просьба попинать.

Код


/**
 * Singleton pattern для PDO
 * 
 */
class PDODB extends PDO {
    
    public function __construct($options = null) {
        if($options === null && isset($GLOBALS['cfg']['database'])) {
            $pdo = $GLOBALS['cfg']['database']['pdo'];
            $options = array_merge($GLOBALS['cfg']['database'], $GLOBALS['cfg'][$pdo]);
        }
        
        try {
            // для mysql и pgsql конструкторы и dsn отличаются
            switch($options['pdo']) {
                case 'pgsql': 
                    $dsn = $options['pdo'] . 
                           ':host=' . $options['host'] . 
                           ' port=' . $options['port'] .
                           ' dbname=' . $options['dbname'] . 
                           ' user=' . $options['user'] . 
                           ' password=' . $options['password'];
                    parent::__construct($dsn);
                    break;
                    
                case 'mysql':
                    $dsn = $options['pdo'] . ':dbname=' . $options['dbname'] . ';host=' . $options['host'];
                    $user = $options['user'];
                    $password = $options['password'];
                    
                    parent::__construct($dsn, $user, $password);
                    
//                    $this->exec("SET CHARACTER SET utf8");
//                    $this->exec("SET NAMES utf8");
                    break;
                    
                default:
                    // если драйвер не указан
                    throw new Exception('Not found PDO driver.');
            }
            
            // set error mode
            $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
            
            // set default fetch mode
            $this->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
        } catch (Exception $e) {
            die ('Connection failed: ' . $e->getMessage());
        }        
    }
    
    /**
     * синглтон паттерн для PDODB
     *
     * @param array $options
     * @return PDODB Object
     */
    public static function getInstance($options = null) {
        static $_instance;

        if ($_instance === null) {
            $_instance = new self($options = null);
        }
        return $_instance;
    }
    
    /**
     * возвращает ассоциативный массив значений из первой строки 
     * или null если запрос вернул пустой результат
     *
     * @param   string $sql
     * @return  list|null
     */    
    public function getRow($sql) {
        $sth = $this->query($sql);
        $result = $sth->fetch(PDO::FETCH_ASSOC);

        if (isset($result)) {
            return $result;
        }
        
        return null;        
    }
    
    /**
     * возвращает единственное скалярное значение из первого столбца первой 
     * записи 
     * или null если запрос вернул пустой результат
     *
     * @param   string $sql
     * @return  string|null
     */
    public function getOne($sql) {
        $sth = $this->query($sql);
        
        $result = $sth->fetch(PDO::FETCH_NUM);
        if (isset($result[0])) {
            return $result[0];
        }
        
        return null;
    }

    /**
     * генерация sql запроса на вставку данных
     *
     * @param string $tableName
     * @param array $metas
     * @param array $values
     * @return string
     */
    protected function generateSqlInsert($tableName, $values) {
        return "INSERT INTO 
                    $tableName 
                (" . implode(array_keys($values), ', ') . ")
                VALUES (" . $this->implodeQuoted($values, ', ') .") ";
    }
    
    /**
     * добавляет кавычки к строковым значениям
     *
     * @param array $values
     * @param string $delimiter
     * @return string
     */
    private function implodeQuoted(&$values, $delimiter) {
        $sql = '';
        $flagIsFirst = true;
        
        foreach($values as $value) {
            if ($flagIsFirst) {
                $flagIsFirst = false;
            } else {
                $sql .= $delimiter;
            }
            
            if ($value == 'now()') {
                $sql .= 'now()';
                continue;
            }
            
            if (gettype($value) == 'string') {
                $sql .= $this->quote($value, PDO::PARAM_STR);
            } else {
                $sql .= $this->quote($value, PDO::PARAM_INT);
            }
        }
        
        return $sql;
    }    
    
}

PM MAIL ICQ   Вверх
awers
Дата 19.4.2008, 09:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1465
Регистрация: 22.3.2006
Где: Россия, Таганрог

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



Оо первый принцип синглетона - отсутствие __construct... замени его к примеру на init()

Почему static $_instance находится внутри public static function getInstance ? Даже если это работает - это муветон
PM MAIL WWW ICQ Skype   Вверх
ST_Falcon
Дата 19.4.2008, 18:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 330
Регистрация: 14.11.2003
Где: Львов

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



awers, 
Цитата

первый принцип синглетона - отсутствие __construct... замени его к примеру на init()


точнее не отсутствие __construct(), а отсутствие доступа к нему. 
хотя в целом ты прав. просто сначала это был Singleton/Adapter, с private __construct(). но потом мне надоело переписывать стандартные методы и я наследовал PDO, а так как в PDO конструктор public, то у потомка тоже пришлось сделать его public. в общем провтыкал. ок. это я переделаю.

Цитата
Почему static $_instance находится внутри public static function getInstance ? Даже если это работает - это муветон 


ну конечно работает, это ведь статическая переменная. а почему муветон? мне так кажется более удобным. в примерах Singleton паттерна я видел оба варианта  (php, с++/c#). 
PM MAIL ICQ   Вверх
flashaa
Дата 19.4.2008, 19:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(ST_Falcon @  19.4.2008,  18:43 Найти цитируемый пост)
ну конечно работает, это ведь статическая переменная. а почему муветон? мне так кажется более удобным. в примерах Singleton паттерна я видел оба варианта  (php, с++/c#).  

Эта статическая переменная доступна только в ф-ции getInstance, а она, вероятно, может понадобиться в других методах класса, потому лучше вынести в ее в класс.
PM MAIL   Вверх
ST_Falcon
Дата 19.4.2008, 21:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 330
Регистрация: 14.11.2003
Где: Львов

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



flashaa, 
Цитата
Эта статическая переменная доступна только в ф-ции getInstance, а она, вероятно, может понадобиться в других методах класса, потому лучше вынести в ее в класс.


Но ведь getInstance инициализирует и возвращает объект класса. В других методах используем просто this или self. Честно говоря не могу представить другие методы в которых может понадобиться $_instance...  smile 
PM MAIL ICQ   Вверх
flashaa
Дата 19.4.2008, 21:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



ST_Falcon, вы на начальном этапе себя ограничиваете тем, что к члену с объектом имеет доступ только метод getInstance. Вот для чего вам это? Чего вы добьетесь ? Я честно говоря никогда не видел такого хранения.
Примера злободневного привести не могу. Вспоминается мне то, что в классе для подключений к БД у меня однажды синглтон перерос в т.н. мультисинглтон - несколько объектов. Т.к. подключение могло быть к разным серверам БД и у меня было принято решение хранить отдельный объект для разных сочетаний юзер+хост. Тут уж self и this не поможет, т.к. нужно хранить несколько объектов. Хотя вообщем думаю и тут можно было бы все это сокрыть внутри getInstance... Вообщем наверно никакого примера привести не могу... Просто интересует, зачем сокрыть внутри метода и ограничивать доступ к члену из других методов ?

Это сообщение отредактировал(а) flashaa - 19.4.2008, 21:59
PM MAIL   Вверх
ST_Falcon
Дата 19.4.2008, 22:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 330
Регистрация: 14.11.2003
Где: Львов

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



flashaa, инкапсуляция smile
а если серьёзно, то никаких объективных причин на это у меня нету. но и моветоном я это не считаю.

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


PM MAIL ICQ   Вверх
flashaa
Дата 19.4.2008, 23:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



ST_Falcon, я тоже не считаю моветоном, просто вижу возможные ограничения в будущем.
По поводу разных форматов DSN, вероятно потому что драйверы к каждому движку БД разрабатывались раздельно, вот и разошлись в стандартах.
PM MAIL   Вверх
MrZLO
Дата 11.3.2009, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



тут конструктор закрытый сделать не получится, т.е. класс наследуется от PDO
Access level to Database::__construct() must be public (as in class PDO)

обёртку с "одиночкой" (синглтон) можно так делать
http://www.apprendre-php.com/tutoriels/tut...egrant-pdo.html


Это сообщение отредактировал(а) MrZLO - 11.3.2009, 12:25
PM MAIL WWW   Вверх
MoLeX
Дата 11.3.2009, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Местный пингвин
****


Профиль
Группа: Модератор
Сообщений: 4076
Регистрация: 17.5.2007

Репутация: 7
Всего: 140



MrZLO, смотри на дату темы, прошел почти год. автор давным-давно нашел решение


--------------------
Amazing  smile 
PM MAIL WWW ICQ   Вверх
  
Закрытая темаСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Базы Данных | Следующая тема »


 




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


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

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