Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: PDO Singleton private constructor.

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Без описания
sweb
Отправлено: 11 Мая, 2013 - 10:24:29
Post Id


Новичок


Покинул форум
Сообщений всего: 23
Дата рег-ции: Окт. 2011  


Помог: 0 раз(а)




Доброго времени суток!

Появилась необходимость реализации паттерна "одиночки" для класса базы данных наследуемого от PDO, и все было бы ничего, если бы не одно НО, в PDO конструктор имеет protected аксессор, и конструкция вида:
PHP:
скопировать код в буфер обмена
  1.  
  2. class Database extends PDO {
  3.     private __construct () {}
  4. }
  5.  
приводит к фатальной ошибке, что вообщем то логично. А вот если сделать так:
PHP:
скопировать код в буфер обмена
  1.  
  2. class Database extends PDO {
  3.     private Database () {}
  4. }
  5.  
то все работает, и вызов new Database выдает фатал, чего мы впринципе и хотели добится.
Вопрос: на сколько разумно использование данной реализации? Ведь мы фактически сделали из protected - private, хорошо ли это?
 
 Top
esterio
Отправлено: 11 Мая, 2013 - 10:35:09
Post Id



Активный участник


Покинул форум
Сообщений всего: 5025
Дата рег-ции: Нояб. 2012  
Откуда: Украина, Львов


Помог: 127 раз(а)




а protected чем не угодил? млм там все таки public
 
 Top
sweb
Отправлено: 11 Мая, 2013 - 10:38:13
Post Id


Новичок


Покинул форум
Сообщений всего: 23
Дата рег-ции: Окт. 2011  


Помог: 0 раз(а)




esterio пишет:
а protected чем не угодил? млм там все таки public

Да, прошу прощения, там public. Но сути дела не меняет.
 
 Top
esterio
Отправлено: 11 Мая, 2013 - 10:50:13
Post Id



Активный участник


Покинул форум
Сообщений всего: 5025
Дата рег-ции: Нояб. 2012  
Откуда: Украина, Львов


Помог: 127 раз(а)




еще как меняет.
в принципе ваш подход хот. и работает но не верен. ета фича еще с пхп 4 и может быть удалена. я бы сделал так
- или оставил как есть public в случае если только вы будете использовать
- переопределил бы конструктор и требовал длполнительный параметр
- поменял концепцию - тоесть вместо init будет конструктор который сверяет статическу переменню. и в случае когда ьам есть уже екземпляр бросать исключение
- вырубал бы ошибки - крайне не рекомендую
 
 Top
sweb
Отправлено: 11 Мая, 2013 - 10:57:43
Post Id


Новичок


Покинул форум
Сообщений всего: 23
Дата рег-ции: Окт. 2011  


Помог: 0 раз(а)




esterio пишет:
ета фича еще с пхп 4 и может быть удалена.

Вот это собсвенно, мне и нужно было. Спасибо.
Так же прислушаюсь к вашим советам.
 
 Top
Мелкий Супермодератор
Отправлено: 11 Мая, 2013 - 11:16:36
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Одиночка обычно не наследуется, а включается в класс.
Как-то так (копипаст моего класса, только не уверен, последней ли версии):
PHP:
скопировать код в буфер обмена
  1. <?PHP
  2. class DB {
  3.         private static $instance;
  4.         public static function instance() {
  5.                 if (!isset(self::$instance)) {
  6.                         $className = __CLASS__;
  7.                         self::$instance = new $className;
  8.                         }
  9.                 return self::$instance;
  10.                 }
  11.  
  12.         protected $link;
  13.         private function __construct() {
  14.                 $this->connect();
  15.                 }
  16.         public function __destruct() {
  17.                 unset($this->link);
  18.                 }
  19.         private function connect() {
  20.                 $config = config::instance('db');
  21.                 $this->link = new PDO('mysql:host='.$config['host'].';dbname='.$config['base'].';charset='.$config['charset'],
  22.                                                 $config['user'],
  23.                                                 $config['pass'],
  24.                                                 array(
  25.                                                         PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,
  26.                                                         PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
  27.                                                         ));
  28.                 $this->link->exec("SET NAMES ".$config['charset']);
  29.                 }
  30.         private $bIsSimulate = false;
  31.         public function simulate($bIsSimulate) {
  32.                 $this->bIsSimulate = $bIsSimulate;
  33.                 }
  34.         public function exec($sQuerySQL, array $rgParams = array()) {
  35.                 if ($this->bIsSimulate) {
  36.                         var_dump($sQuerySQL, $rgParams);
  37.                         return (object) array(
  38.                                 'id'=>0,
  39.                                 'affected'=>0
  40.                                 );
  41.                         }
  42.                 if (empty($rgParams)) $iAffectedRows = $this->link->exec($sQuerySQL);
  43.                 else {
  44.                         $rPrepared = $this->link->prepare($sQuerySQL);
  45.                         $rPrepared->execute($rgParams);
  46.                         $iAffectedRows = $rPrepared->rowCount();
  47.                         }
  48.                 return (object) array(
  49.                                 'id'=>$this->link->lastInsertId(),
  50.                                 'affected'=>(int)$iAffectedRows
  51.                                 );
  52.                 }
  53.         public function query($sQuerySQL, array $rgParams = array()) {
  54.                 if (empty($rgParams)) return $this->link->query($sQuerySQL);
  55.                 else {
  56.                         $rPrepared = $this->link->prepare($sQuerySQL);
  57.                         $rPrepared->execute($rgParams);
  58.                         return $rPrepared;
  59.                         }
  60.                 }
  61.         public function begin() {
  62.                 $this->link->beginTransaction();
  63.                 }
  64.         public function commit() {
  65.                 $this->link->commit();
  66.                 }
  67.         public function rollback() {
  68.                 $this->link->rollback();
  69.                 }
  70.  
  71.         public function ping() {
  72.                 //переустанавливает соединение, если то случайно умерло
  73.                 try {
  74.                         $this->link->query('SELECT 1');
  75.                 } catch (PDOException $e) {
  76.                         $this->connect();
  77.                         }
  78.                 }
  79.         }
  80.  


-----
PostgreSQL DBA
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Объектно-ориентированное программирование »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB