Поругайте Static wrapper

Проверенные VDS на SSD в Европе и России

Тема в разделе "Вопросы по программированию на РНР", создана пользователем Фанат, 19 янв 2014.

  1. Фанат

    Фанат oncle terrible Команда форума

    Сообщения:
    39.634
    Ваш город:
    Moscow, Russia
    Adress:
    Moscow, Russia
    Country:
    Location on Map:
    Как вы знаете, я не слишком силён в оопе.
    Код цельнотянутый у Никиты Попова из его ПДО враппера трехгодичной давносте.

    PHP:
    class DB
    {
        protected static 
    $instance null;

        final private function 
    __construct() {}
        final private function 
    __clone() {}

        public static function 
    instance($cfg = array())
        {
            if (
    self::$instance === null)
            {
                require 
    dirname(__FILE__)."/safemysql.class.php";
                
    self::$instance = new safemysql($cfg);
            }
            return 
    self::$instance;
        }
      
        public static function 
    __callStatic($method$args)
        {
            return 
    call_user_func_array(array(self::instance(), $method), $args);
        }
    }
    Что здесь плохого и надо ли его улучшить или так сойдёт?

    Я знаю, многие сделали свой. Делитесь, если не жалко
     
  2. riff

    riff Новичок

    Сообщения:
    571
    Adress:
    Moscow (Tsentralnyy administrativnyy okrug), Russia
    Country:
    Location on Map:
    1. DB::instance(с параметрами) позволено вызывать один раз, в последствии только без параметров. Поэтому instance(с параметрами) должен быть обязательно однажды объявлен, следовательно его будут выносить в раздел загрузки. Без этого дальнейшая работа бессмысленна, более того чревата ошибками: например, не подключил я instance(с параметрами), но начал пользоваться instance(), добрый DB мне его создаст, но не тот что нужен, а будет создан с параметрами по-умолчанию.

    2. DB::instance() - не понятно, что я создаю: по идее класс DB, а на самом деле safemysql.
    Например, создам я "class My_DB extends DB" с нужными мне "public function", радостный напишу "My_DB::instance()->my_function" и получу ошибку.

    Поэтому "instance($cfg)" я бы переименовал в типа "create_safemysql($cfg)", для вызова её единожды в автозагрузке (при запуске проекта).
    А "publuc static $instance" переименовал бы в "public static $safemysql" и соответственно в коде писал бы DB::$safemysql->query(...).
     
    Последнее редактирование: 19 янв 2014
  3. флоппик

    флоппик promotor fidei Команда форума Партнер клуба

    Сообщения:
    4.719
    Ваш город:
    Павлодар, Казахстан
    Adress:
    Pavlodar, Kazakhstan
    Country:
    Location on Map:
    ну и static:: же, уже сколько лет прошло, уже можно.
     
    AmdY нравится это.
  4. riff

    riff Новичок

    Сообщения:
    571
    Adress:
    Moscow (Tsentralnyy administrativnyy okrug), Russia
    Country:
    Location on Map:
    И ещё, Фанат, я бы посоветовал не писать класс DB. А остановиться на safemysql. Дальше "я" (как пользователь) сам создам нужный мне DB, и в нём инициализирую safemysql, (например в функции коннекта к базе). Зачем ты его(DB) пишешь?
     
    Последнее редактирование: 21 янв 2014
  5. Vladson

    Vladson Сильнобухер

    Сообщения:
    859
    Ваш город:
    Tallinn, Estonia
    Adress:
    Tallinn, Estonia
    Country:
    Location on Map:
    Главное чтоб не у Евгения :D
     
    keltanas нравится это.
  6. HraKK

    HraKK Мудак Команда форума

    Сообщения:
    3.511
    Ваш город:
    Киев
    Adress:
    Kiev, Ukraine
    Country:
    Location on Map:
    А зачем, вообще, делать DB звездным объектом?
     
  7. Вурдалак

    Вурдалак Newbie

    Сообщения:
    5.862
    Ваш город:
    Russia, Moscow
    Adress:
    Moscow, Russia
    Country:
    Location on Map:
    Потому что Фанат, так сказать, старой закалки. Проще дернуть статический метод и "немного" поговнокодить, нежели юзать какие-то навороченные и заумные best practices, которые придумали от большого ума. Мол, все равно DB в 95% будет синглтоном, в жопу пошли остальные 5%.
    sheldon_sarcasm.jpg
     
  8. WMix

    WMix герр M:)ller Партнер клуба

    Сообщения:
    5.680
    Ваш город:
    Berlin
    Adress:
    Berlin, Germany
    Country:
    Location on Map:
    твоя идея это запись типа DB::getOne('select version()'), если я правильно понимаю. ограничения думаю тебе известны, всего одна база. а выгрыш простота и досигаемость отовсюду.
    если строчку слегка удленить, Db::getAdapter($name)->getAll('select version()') то решается и досигаемость и различные драйвера и множество connections в одном проекте и на модель определенный адаптер про который модель ничего не знает.
    Это можно добавить после (не переписывая программу), ожидая от краткой записи некий "default adapter", а от длинной - специфический.
    только придумать способ добавлять новые драйвера (описать driver-interface), connections, а также свободу выбора "default adapter"
    до тех пока не существует перечисленного, у разработчика взявшего твою библиотеку при появлении одной из задач, не остается выбора, кроме как (пере/до)писать твой класс самому, а значит забыть о обновлениях твоей ветки.
     
    Последнее редактирование: 19 янв 2014
  9. Фанат

    Фанат oncle terrible Команда форума

    Сообщения:
    39.634
    Ваш город:
    Moscow, Russia
    Adress:
    Moscow, Russia
    Country:
    Location on Map:
    Ну вообще Вурдалак отчасти прав.
    Но в основном - постоянно спрашивают статику. Для классическогоговнокода уж очень она удобна.
     
  10. Тугай

    Тугай Новичок

    Сообщения:
    231
    Adress:
    Dnipro, Ukraine
    Country:
    Location on Map:
    Код идеален, но можно похоливарить про instance() и getInsatace() :)
    Как бы instance() ближе к micisofoft, а getInsatace() к unix )))
     
  11. Absinthe

    Absinthe жожо

    Сообщения:
    3.416
    Ваш город:
    Москва
    Adress:
    Moscow, Russia
    Country:
    Location on Map:
    Покажи пример кода с работой с тремя базами.
     
  12. Vladson

    Vladson Сильнобухер

    Сообщения:
    859
    Ваш город:
    Tallinn, Estonia
    Adress:
    Tallinn, Estonia
    Country:
    Location on Map:
    Absinthe, а если нету его, значит ли это что такой вариант невозможен ???
     
  13. Absinthe

    Absinthe жожо

    Сообщения:
    3.416
    Ваш город:
    Москва
    Adress:
    Moscow, Russia
    Country:
    Location on Map:
    Кого нету?
     
  14. Фанат

    Фанат oncle terrible Команда форума

    Сообщения:
    39.634
    Ваш город:
    Moscow, Russia
    Adress:
    Moscow, Russia
    Country:
    Location on Map:
    Это очень хороший вопрос.

    Во-первых, стандартный ответ на него - это
    PHP:
    $db1 = new safemysql();
    $db2 = new safemysql();
    DB::instance();
    Но интереснее, конечно же, сделать поддержку теми же синглетонами.
    Вот что у меня получилось, опять же, методом тупой копипасты:
    PHP:
    class DB
    {
        protected static 
    $instance = array();

        final private function 
    __construct() {}
        final private function 
    __clone() {}

        public static function 
    instance($cfg = array())
        {
            
    $className get_called_class();
            if(!isset(
    self::$instance[$className]))
            {
                require_once 
    dirname(__FILE__)."/safemysql.class.php";
                
    self::$instance[$className] = new safemysql($cfg);
            }
            return 
    self::$instance[$className];
        }
     
        public static function 
    __callStatic($method$args)
        {
            return 
    call_user_func_array(array(self::instance(), $method), $args);
        }
    }
    class 
    DB2 extends DB {}
    DB2::query("set @aaa:=1");
    echo 
    DB::getOne('SELECT @aaa');
    echo 
    DB2::getOne('SELECT @aaa');
    Я, кстати, давно уже мечтал делать ЭТО екстендом.
     
  15. Absinthe

    Absinthe жожо

    Сообщения:
    3.416
    Ваш город:
    Москва
    Adress:
    Moscow, Russia
    Country:
    Location on Map:
    > Я, кстати, давно уже мечтал делать ЭТО екстендом.

    Кажется очень грязным кодом.
     
  16. Фанат

    Фанат oncle terrible Команда форума

    Сообщения:
    39.634
    Ваш город:
    Moscow, Russia
    Adress:
    Moscow, Russia
    Country:
    Location on Map:
    Можешь как-то более развёрнуто? Я не держусь за этот метод, но хочется понимать в чем грязь и какие альтернативы.
     
  17. Absinthe

    Absinthe жожо

    Сообщения:
    3.416
    Ваш город:
    Москва
    Adress:
    Moscow, Russia
    Country:
    Location on Map:
    Расширение класса должно дополнять (Лисков) принцип работы класса.
    Тут же это делается как копипаста, засахаренная синтаксисом 5.3. Новой логики не добавляется.

    А если 11 баз, будем заводить новых 11 файлов с разными классами?
    А если несколько баз будут иметь одну и ту же структуру и надо будет между ними выбирать?
     
    Hello и WMix нравится это.
  18. Вурдалак

    Вурдалак Newbie

    Сообщения:
    5.862
    Ваш город:
    Russia, Moscow
    Adress:
    Moscow, Russia
    Country:
    Location on Map:
    Фанат, у тебя есть некий объект, который зависит от базы данных, неважно от какой. Ты туда хардкодишь DB, а потом в какой-то момент понимаешь, что было бы круто, чтобы зависимость была от safemysql, а не DB (DB2, ...), но внезапно ты осознаешь, что ты увлекся своими синглтонами и просто так заинжектить уже не выйдет.

    Что только не придумают, лишь бы не юзать DI.
     
    Hello и WMix нравится это.
  19. WMix

    WMix герр M:)ller Партнер клуба

    Сообщения:
    5.680
    Ваш город:
    Berlin
    Adress:
    Berlin, Germany
    Country:
    Location on Map:
    PHP:
    class UsersService{
    // ...
    public function getById($id){
      return new 
    User (
        
    DB::getRow// тут захардкодили. класс UsersService, придется переписывать для другой базы
          
    'select * from users ...'$id
        
    )
      );
    }
    }
     
  20. Фанат

    Фанат oncle terrible Команда форума

    Сообщения:
    39.634
    Ваш город:
    Moscow, Russia
    Adress:
    Moscow, Russia
    Country:
    Location on Map:
    Зачем новый файл для одной строчки?

    Вообще, я не думал углубляться в дискуссию "чем плох синглетон".