За последние 24 часа нас посетили 20658 программистов и 1708 роботов. Сейчас ищут 1476 программистов ...

Сокращение Singleton / хорошо или нет?

Тема в разделе "PHP для профи", создана пользователем Артем Кошкин, 1 ноя 2017.

  1. Артем Кошкин

    Артем Кошкин Новичок

    С нами с:
    1 ноя 2017
    Сообщения:
    6
    Симпатии:
    0
    Всем привет.

    В своих приложениях я использую разничные классы, это может быть User, MySQL, ...
    Основные классы (например User, MySQL) я использую через singleton.

    Для этого у меня есть класс контроллера:
    PHP:
    1. class Controller
    2. {
    3.  
    4.     private static $_inst = NULL;
    5.  
    6.     private $_data = array();
    7.  
    8.     public static function getInstance()
    9.     {
    10.         if (self::$_inst === NULL)
    11.             self::$_inst = new self();
    12.  
    13.         return self::$_inst;
    14.     }
    15.  
    16.     public function __set($index, $value)
    17.     {
    18.         $this->_data[$index] = $value;
    19.     }
    20.  
    21.     public function __get($index)
    22.     {
    23.         return $this->_data[$index];
    24.     }
    25.  
    26.     public function __isset($index)
    27.     {
    28.         return isset($this->_data[$index]);
    29.     }
    30.  
    31.     public function __unset($index)
    32.     {
    33.         unset($this->_data[$index]);
    34.     }
    35.  
    36. }
    А дальше я делаю небольшую хитрость для того, что бы экономить время и не парится о том что где доступно. Мне удобно что что я могу обратиться к базе из любого места.

    PHP:
    1. function c()
    2. {
    3.     return grut\Controller::getInstance();
    4. }
    5.  
    6. function my()
    7. {
    8.     return isset(c()->my) ? c()->my : c()->my = new MySQLi(...);
    9. }
    Вопрос - насколько это правильно?

    Плюсы:
    • Удобство, например запросы к базе из любого места выглядят как my()->query(...) или залогинен ли пользователь bool user()->authorized без дополнительного кода, т.е. все максимально коротко.
    Минусы: ??? Почему так не делают в фреймворках?
     
  2. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    просто это лишние телодвижения
     
  3. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.593
    Симпатии:
    362
    @Артем Кошкин, каждый раз вызывать метод getInstance() - явное излишество :)
     
  4. Алекс8

    Алекс8 Активный пользователь

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    нечто похожее в движке магазина Simpla...
    только там еще все api классы регистрируются в основном классе.. в виде массива.. имя_класса => файл_класса
    и потом уже везде можно их сразу использовать без создания дополнительных экземпляров класса..
    все остальные классы представлений уже являются дочерними классами основного класса..

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

    а так удобно все.. но это как бы не по православному)) сейчас все ударились в ООП)) и функция находящаяся вне класса вызывает бурю противоречивых эмоций)))
    а как по мне нормально))
    все ИМХО))
     
  5. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.794
    Симпатии:
    1.331
    Адрес:
    Лень
    скажи это обвертке для PDO

    мы же не насилуем бд подключениями в 300 раз, так как существует условие "заглушка"

    если нулл то подключить и вывести...

    далее просто вывод...
    --- Добавлено ---
    в Уииии та же фишка
     
  6. Алекс8

    Алекс8 Активный пользователь

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    ну в yii2 вроде не совсем так.... там все равно надо создавать явно объекты..
    а в simpla просто пишешь $this->product->get(12)
    где this любой класс в котором ты сейчас находишься)
    а product как раз API класс)) в yii2 это модель называется - с базой все операции делает..
    ну а вьюхи в simla совмещены с контроллерами..
    а 12 это ID продукта который достать надо)
     
  7. Артем Кошкин

    Артем Кошкин Новичок

    С нами с:
    1 ноя 2017
    Сообщения:
    6
    Симпатии:
    0
    т.е. грубо говоря каждое обращение к базе - одно лишнее сравнение + один лишний вызов isset. По мне так это вообще не излишество, это нормально.

    Может можно придраться с точки зрения безопастности? Для меня сейчас это очень важно.

    Вижу пару вопросов:

    1) Плохо ли вызывать класс из самой обычной функции? Почему? По сути функция отдает только ссылку. Вроде ОК? Что то меня смущает, сам не могу понять что... Наверное то что в больших фреймворках я такого не видел. Наверное потому что действительно это НА ВИД не по православному )

    2) А если не так, то как лучше? Что сейчас модно? ))
     
  8. Алекс8

    Алекс8 Активный пользователь

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    делайте так как удобно Вам в проектах которые Вы пишите с нуля.. главное что бы код был структурирован, читабелен, и документирован..
    если работаете с CMS или фреймворками - следуйте их религии..
    правильный вариант тот который работает и не вызывает избыточную нагрузку..
    одна функция вне класса не вызовет нагрузку)) нравится - на здоровье)
     
  9. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.584
    Симпатии:
    1.762
    Да делают и так. Другое дело, если у тебя столько синглтонов, то это уже не лучшее решение. Что, контроллер только один что-ли? Подходов к тому, как строить класс модели, много. А вообще, лучше осваивайте di-контейнеры. Есть независимые, без связи с фреймворком, например http://php-di.org/
     
  10. Артем Кошкин

    Артем Кошкин Новичок

    С нами с:
    1 ноя 2017
    Сообщения:
    6
    Симпатии:
    0
    ну это как бы только пример ) по факту таких функций чуть больше чем одна...
    с()->conf = [... мои настройки которые доступны везде...]
    c()->mem = [... всякие расшифровки статусов, обернутые в gettext ...]
    my()-> база данных #1
    my_tst()-> база данных #2
    user()-> класс пользователя, там же методы логина, проверки, методы смены паролей и т.д. все про пользователя
    core()-> класс рендеринга страницы, надо для того что бы я например из либого места мог сделать core()->loadJS('/path/to/file.js') который потом подкинется к выводу html.
    --- Добавлено ---
    контролер один. Можно конечно все класы оснастить своими синглетонами вообще но зачем?

    Спасибо за ссылку! Интересно 100%, изучу.
     
  11. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.584
    Симпатии:
    1.762
    Ну у меня всегда много контроллеров, один для работы с профилем, другой - ещё для чего-нибудь. Иначе же разрастаться будет сильно единственный контроллер. Если у вас одни синглтоны, то классы вам и не нужны по факту. Может стоит полностью на процедурах остановиться
     
  12. Артем Кошкин

    Артем Кошкин Новичок

    С нами с:
    1 ноя 2017
    Сообщения:
    6
    Симпатии:
    0
    Как разрастаться? Я свой контроллер не трогал уже очень давно... годы. Т.е. это просто типо стек для классов. А учитывая что сейчас пхп хранит не классы целиком а только ссылки на классы - значит это стек ссылок на классы. Процедуры (я так понял имеются ввиду обычные функции) не подойдут точно. Везде где они подходят я их использую...

    Есть примеры когда надо хоть 2 контроллера? Я чувствую что я что то упускаю =)
     
  13. Алекс8

    Алекс8 Активный пользователь

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    Вы под контроллером наверно имеете ввиду роутинг и/или автозагрузку классов?
    Потому что под каждый экшен полается свой контроллер делать...
     
  14. Артем Кошкин

    Артем Кошкин Новичок

    С нами с:
    1 ноя 2017
    Сообщения:
    6
    Симпатии:
    0
    Я имею ввиду контейнер. У меня просто класс криво называется. Я про класс из первого поста.
     
  15. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.584
    Симпатии:
    1.762
    Ой, я увидел название "контроллер" и не пригляделся, что это у тебя реестр на самом деле. Контроллер - это другое должно быть. Контроллер - класс, отвечающий за взаимодействие с пользователем. Registry - да, типичный синглтон.
     
  16. Артем Кошкин

    Артем Кошкин Новичок

    С нами с:
    1 ноя 2017
    Сообщения:
    6
    Симпатии:
    0
    Извиняюсь что ввел в заблуждение. Короче говоря я так понял что в моем методе нет ничего криминального. Реестр один у меня конечно, контроллеры я использую как php файлы, немного устарелый подход...