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 :: Стоит ли создавать единственный экземпляр класса?

 PHP.SU

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


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

> Без описания
morph-x
Отправлено: 13 Ноября, 2011 - 14:31:47
Post Id



Гость


Покинул форум
Сообщений всего: 111
Дата рег-ции: Июнь 2011  


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




Короче есть у меня класс для работы с БД:
PHP:
скопировать код в буфер обмена
  1. <?PHP
  2.  
  3. class Db {
  4.   private $connection;
  5.    
  6.   public function __construct() {
  7.       // Устанавливаем соединение с БД в переменную $connection
  8.   }
  9.    
  10.   public function query($query) {
  11.       // Выполняем запрос и возвращаем результат
  12.   }
  13. }


Это как бы урезанная версия, но для наглядности сойдет. Суть в том, что соединение с БД у меня будет только одно. Стоит ли создавать единственный экземпляр этого класса? Какой из этих вариантов наиболее правильный?

Вариант 1
PHP:
скопировать код в буфер обмена
  1. <?PHP
  2.   $db = new Db;
  3.   $db->query(/* Здесь запрос */);
  4. ?>


Вариант 2
PHP:
скопировать код в буфер обмена
  1. <?PHP
  2.   Db::query(/* Здесь запрос */);
  3. ?>


Или предложите свой вариант, если эти два считаете неправильными. Заранее спасибо!
 
 Top
DeepVarvar Супермодератор
Отправлено: 13 Ноября, 2011 - 14:36:37
Post Id



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


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


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




Нужно реализовать синглтон.
Дело не в том какой из вариантов правильный.
Дело в ограничении кол-ва до единственного экземпляра СОЕДИНЕНИЯ а не объекта.
И делается это ограничение со вторым вариантом.
(Добавление)
Конструктор должен быть приватным,
а метод вызова единственного экземпляра публичным.
PHP:
скопировать код в буфер обмена
  1. class db {
  2.  
  3.   protected static $db;
  4.   protected static $link;
  5.  
  6.   public static function getInstance() {
  7.     if (self::$db === null) self::$db = new self();
  8.     return self::$db;
  9.     }
  10.  
  11.   private function __construct() {
  12.     // TODO что-то там у вас
  13.     }
  14.  
  15.   }

(Добавление)
Так вы сможете проверить в методе getInstance (можете назвать его иначе, хоть checkUniqum)
был ли инициализирован ранее данный объект, и если был, вернуть его, в противном случае - инициализировать.
 
 Top
morph-x
Отправлено: 13 Ноября, 2011 - 15:04:20
Post Id



Гость


Покинул форум
Сообщений всего: 111
Дата рег-ции: Июнь 2011  


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




Я так понимаю, что бы создать экземпляр данного класса нужно сделать так:
PHP:
скопировать код в буфер обмена
  1. <?PHP $db = Db::getInstance(); ?>
 
 Top
DeepVarvar Супермодератор
Отправлено: 13 Ноября, 2011 - 15:18:29
Post Id



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


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


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




Да.
 
 Top
morph-x
Отправлено: 13 Ноября, 2011 - 15:21:00
Post Id



Гость


Покинул форум
Сообщений всего: 111
Дата рег-ции: Июнь 2011  


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




DeepVarvar, большое спасибо!
 
 Top
White
Отправлено: 13 Ноября, 2011 - 16:26:25
Post Id



Частый посетитель


Покинул форум
Сообщений всего: 830
Дата рег-ции: Июнь 2011  
Откуда: Днепропетровск


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




Существует ли вероятность, что объект вашего класса будет передаваться в качестве аргумента какой либо функции? если нет, тогда какой смысл создавать каждый раз ссылку на единственный объект данного класса, если мы прекрасно можем без него обойтись?
PHP:
скопировать код в буфер обмена
  1. class DB {
  2.   private static $connection;
  3.  
  4.   public static function query() {
  5.     ...
  6.   }
  7. }

класс ведь не реализует никакую бизнес логику вашего приложения, так?
другой вопрос, если вы собираетесь использовать один из шаблонов ORM (TDG, DataMapper, ActiveRecord...). В таком случае данный класс будет наследоваться другими классами, реализующими модели данных вашего приложения, в данной ситуации уже не один, а множество объектов будут реализовывать его методы. Выход в такой ситуации может быть следующим:
PHP:
скопировать код в буфер обмена
  1. class DB {
  2.   private static $connection;
  3.  
  4.   public function __construct() {
  5.     if(!$connection) self::connect();
  6.   }
  7.  
  8.   protected static function connect() {
  9.     ...
  10.   }
  11. }


-----
if(time()>1356048000) die();
 
 Top
DeepVarvar Супермодератор
Отправлено: 13 Ноября, 2011 - 16:46:45
Post Id



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


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


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




White как-то ковырял многолинковый класс. Так не доковырял, да пока и не нужно.
Там никак не мог сделать чтобы методы запросов к базе понимали несколько подключений.
Типа создавал подключение и ссылку на него сохранял
в ассоциативный массив вида: self::$links['linkname'].
Затем вызывал типа так: self::query($qstr,$linkname);
Но что-то работало только с одним соединением, хотя передавал параметр в запрос.
Щас даже найти не могу куски экспериментов.
Если у вас имеется такое решение - раскурите на примере.
 
 Top
White
Отправлено: 13 Ноября, 2011 - 17:09:38
Post Id



Частый посетитель


Покинул форум
Сообщений всего: 830
Дата рег-ции: Июнь 2011  
Откуда: Днепропетровск


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




DeepVarvar так я ж предлагаю один линк на всех. линк создается через конструктор, один раз, и хранится как свойство класса. просто если класс должен наследоваться, а в случае с ORM это чаще всего так, синглтоном его уже не сделаешь.
(Добавление)
DeepVarvar а что с многолинковым классом не так?
PHP:
скопировать код в буфер обмена
  1. class DB {
  2.   private static $conn=array();
  3.   private $conn;
  4.  
  5.   public function __construct($dbname) {
  6.     if(!$conn[$dbname]) self::connect($dbname);
  7.     $this->conn = self::$conn[$dbname];
  8.   }
  9.  
  10.   public function query($query) {
  11.     mysqli_query($this->conn, $query);
  12.   }
  13.  
  14.   protected static function connect($dbname) {
  15.     $conn[$dbname] = mysqli_connect();
  16.     mysqli_select_db($conn[$dbname], $dbname);
  17.   }
  18. }


мне кажется так должно вполне нормально работать (только передавать параметры в соединение надо)


-----
if(time()>1356048000) die();
 
 Top
DeepVarvar Супермодератор
Отправлено: 13 Ноября, 2011 - 17:37:27
Post Id



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


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


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




White пишет:
мне кажется
вот и мне казалось. Проверяли?
 
 Top
White
Отправлено: 13 Ноября, 2011 - 18:09:57
Post Id



Частый посетитель


Покинул форум
Сообщений всего: 830
Дата рег-ции: Июнь 2011  
Откуда: Днепропетровск


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




DeepVarvar нет, ну если есть сомнения, думаю проверю.


-----
if(time()>1356048000) die();
 
 Top
Stierus Супермодератор
Отправлено: 14 Ноября, 2011 - 09:12:14
Post Id



Рекордсмен по количеству сообщений за 7 дней


Покинул форум
Сообщений всего: 2132
Дата рег-ции: Дек. 2008  
Откуда: Москваль


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




Как одновременно с двумя базами работать будете, если перейдете на синглтон или статик методы ?
 
My status
 Top
caballero
Отправлено: 14 Ноября, 2011 - 10:05:28
Post Id


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


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


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




Цитата:
класс ведь не реализует никакую бизнес логику вашего приложения, так?
другой вопрос, если вы собираетесь использовать один из шаблонов ORM (TDG, DataMapper, ActiveRecord...).

смешались в кучу кони люди.
Синглетон служит именно для
1. обеспечения единственного коннекта
2. избегания использования глобальных переменных
3. коннкета "по первому требованию" когда он понадобися а не каждый раз в том числе на тсраницах не требующих конекта с БД.
Актив рекорд и прочее - это другие классы никак не связаные с синглетоном кроме того что там просто используется коннект как в любом другом месте.

Почему то многое стараются упортно свалить в один клас коннект и методы работы с данными БД. Это разная логика для классов.

Цитата:
Как одновременно с двумя базами работать будете, если перейдете на синглтон или статик методы ?

довольно редкая ситуация но ничто не мешает в синглетоне воткнуть еще один коннект


-----
Бесплатная система складского учета с открытым кодом https://zippy[dot]com[dot]ua/zstore
 
 Top
Stierus Супермодератор
Отправлено: 14 Ноября, 2011 - 10:17:58
Post Id



Рекордсмен по количеству сообщений за 7 дней


Покинул форум
Сообщений всего: 2132
Дата рег-ции: Дек. 2008  
Откуда: Москваль


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




caballero пишет:
довольно редкая ситуация но ничто не мешает в синглетоне воткнуть еще один коннект

Получится фабричный метод - то, что тут и нужно.
 
My status
 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