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 :: extends Singleton

 PHP.SU

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


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

> Без описания
Slimer
Отправлено: 15 Июня, 2016 - 10:36:27
Post Id


Новичок


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


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




Есть класс
PHP:
скопировать код в буфер обмена
  1. namespace A\B;
  2.  
  3. class Singleton
  4. {
  5.         protected static $instance = NULL;
  6.  
  7.         public static function i()
  8.         {
  9.                 if($this->instance === NULL )
  10.                 {
  11.                         $classname = get_called_class();
  12.                         $this->instance = new $classname;
  13.                 }
  14.  
  15.                 return $this->instance;
  16.         }
  17.  
  18. }


Далее наследую его в двух других классах:
PHP:
скопировать код в буфер обмена
  1. namespace A;
  2. class R extends \A\B\Singleton
  3. {
  4.         public function run()
  5.         {
  6. \A\S::i()->run1();
  7. }
  8.  

и
PHP:
скопировать код в буфер обмена
  1. namespace A;
  2. class S extends \A\B\Singleton
  3. {
  4.         public function run1()
  5.         {
  6. }
  7.  

И вот если я из класса R обращаюсь по полному имени к методам класса S, то он ругается, что метод run1() не найден в \A\R. Т.е. он игнорирует указание полного пути и ищет не там.
Используется автозагрузка.
Я так понимаю, что это из-за использования static в Singleton т.е. instance уже присвоен и отдаётся уже созданный объект.

А как тогда наследовать Singleton, чтобы он в каждом классе был свой и не приходилось его писать руками для каждого класса отдельно? Ведь именно для этого придуман extends. Если делаю $instance не protected static получаю ошибку.

(Отредактировано автором: 15 Июня, 2016 - 10:37:36)

 
 Top
T1grOK
Отправлено: 15 Июня, 2016 - 10:42:24
Post Id



Частый гость


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


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




Подсказка. Пул одиночек.


-----
Mysql, Postgresql, Redis, Memcached, Unit Testing, CI, Kohana, Yii, Phalcon, Zend Framework, Joomla, Open Cart, Ymaps, VK Api
 
 Top
skiphog
Отправлено: 15 Июня, 2016 - 10:48:12
Post Id



Частый гость


Покинул форум
Сообщений всего: 139
Дата рег-ции: Дек. 2014  
Откуда: Киров, Россия


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




Если PHP 5.4+
Используйте Trait
Пример найдете по ссылке
https://goo[dot]gl/ihPG2v

(Отредактировано автором: 15 Июня, 2016 - 10:53:52)

 
My status
 Top
Slimer
Отправлено: 15 Июня, 2016 - 12:15:05
Post Id


Новичок


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


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




Спасибо, оба способа работают. Выберу пожалуй Multiton из-за более понятного синтаксиса.

Но тут один вопрос. В примерах, которые я нагуглил встречается ошибка:
PHP:
скопировать код в буфер обмена
  1. public static function getInstance() {
  2.         $className = static::getClassName();
  3.         if (!(self::$instances[$className] instanceof $className)) {
  4.             self::$instances[$className] = new $className();
  5.         }
  6.         return self::$instances[$className];
  7.     }
  8.  

Первый же вызов ругается на self::$instances[$className]. Естественно, его же никто не задавал нигде.
Изменил на

PHP:
скопировать код в буфер обмена
  1.         public static function getInstance()
  2.         {
  3.                 $className = get_called_class();
  4.                 if (isset(self::$instances[$className]))
  5.                 {
  6.                         if (!(self::$instances[$className] instanceof $className))
  7.                         {
  8.                                 self::$instances[$className] = new $className();
  9.                         }
  10.                 } else {
  11.                         self::$instances[$className] = new $className();
  12.                 }
  13.                 return self::$instances[$className];
  14.         }


Правильно?

(Отредактировано автором: 15 Июня, 2016 - 12:25:05)

 
 Top
Viper
Отправлено: 15 Июня, 2016 - 13:55:31
Post Id



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


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


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




Slimer пишет:
Первый же вызов ругается на self::$instances[$className]. Естественно, его же никто не задавал нигде.
ну так переменную класса задать кто мешает?


-----
Список фильмов с описанием, блекджеком и... для Joomla? -> https://киноархив[dot]com
Демо нового движка для сайта php.su -> php[dot]su, проект на гитхабе
 
 Top
Мелкий Супермодератор
Отправлено: 15 Июня, 2016 - 14:06:51
Post Id



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


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


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




isset там нужен, верно.
А вот если инстанс есть, но почему-то другого класса - я бы кидал LogicException

И вообще странно выглядит. Может, лучше Registry?
Или вообще более популярный нынче dependency injection?


-----
PostgreSQL DBA
 
 Top
caballero
Отправлено: 15 Июня, 2016 - 14:59:30
Post Id


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


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


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




не существует причин наследовать синглетон кроме кривой архитектуры


-----
Бесплатная система складского учета с открытым кодом https://zippy[dot]com[dot]ua/zstore
 
 Top
Slimer
Отправлено: 16 Июня, 2016 - 20:34:52
Post Id


Новичок


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


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




caballero пишет:
не существует причин наследовать синглетон кроме кривой архитектуры
это же тупо защита, чтобы не насоздавать лишних объектов случайно. Хоть я и тоже не понимаю как это можно сделать, если подключение к базе, получение настроек и т.д. делаешь один раз и в одном месте.
Но раз есть такая штука - пробую использовать, заодно есть повод научиться чему-то новому.

(Отредактировано автором: 16 Июня, 2016 - 20:35:31)

 
 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