За последние 24 часа нас посетили 54092 программиста и 1799 роботов. Сейчас ищут 2222 программиста ...

Вопрос про классы

Тема в разделе "Прочие вопросы по PHP", создана пользователем kagerr, 20 май 2008.

  1. kagerr

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

    С нами с:
    20 май 2008
    Сообщения:
    17
    Симпатии:
    0
    Здравствуйте. Я вот тут думу думаю... Если не сложно, то поделитесь своими идеями по следующему вопросу:
    Есть разные самописные классы, например CLmysql (БД), CLreport (отчет об ошибках), CLconfig (установка констант) и другие (их еще куча)... Так вот, мне интересно как лучше поступить, чтобы, например, в классе CLconfig можно было и выполнять запросы mysql и, если возникла ошибка, то отправлять ее в отчет об ошибках... Я делаю на данный момент так (код из CLconfig):
    Код (Text):
    1.  function __construct($db,$report)
    2.            {
    3.         if (is_a($db, 'CLmysql')){
    4.             $this->db=$db;
    5.         }else{
    6.             return(false);
    7.         }
    8.        
    9.         if (!is_a($report,'CLreport')) {
    10.             return (false);
    11.                     }else{
    12.             $this->report=$report;
    13.                     }
    14.     }
    extends не пойдет, так как надо наследовать не один, а несколько классов, а делать по типу, что CLreport наследует CLmysql, а CLconfig - CLreport, мне кажется, не очень красиво, так как потом все будет запутано на мой взгляд))
    У кого какие предложения по поводу наилучшей реализации подобной фигни?))
     
  2. Ti

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

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    PHP:
    1. <?
    2. // паттерн Singleton
    3. class CLmysql {
    4.     static private $_instance;
    5.  
    6.  
    7.     /**
    8.      * @return CLmysql
    9.      */
    10.     static function getInstance() {
    11.         if (is_null(self::$_instance)) self::$_instance = new self;
    12.         return self::$_instance;
    13.     }
    14. }
    15.  
    16. // в любом месте
    17. $mysql = CLmysql::getInstance();
     
  3. kagerr

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

    С нами с:
    20 май 2008
    Сообщения:
    17
    Симпатии:
    0
    хм... Ну не плохое решение... Я просто по какой-то причине пропустил мимо себя static... Сейчас хоть восполнил эту потерю...
    Тогда возникает другой вопрос... Что лучше: делать таким образом или просто в классах функции делать static?
     
  4. Ti

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

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    Делать все фунцкии в классах static плохо.
    ООП - Объектно-ориентированное программирование.
    GetInstance не мешает вам создать другой объект, к примеру соединение с другой базой данной. А если все сделать static это будет проблемно.
     
  5. kagerr

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

    С нами с:
    20 май 2008
    Сообщения:
    17
    Симпатии:
    0
    Ну спасибо большое за совет... Код куда красивее станет и удобнее))
     
  6. kagerr

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

    С нами с:
    20 май 2008
    Сообщения:
    17
    Симпатии:
    0
    Я может не совсем разобрался еще, но столкнулся со следующей проблемой: у меня в констуркторе класса CLmysql идет подключение к БД... Следовательно, при использование getInstance, необходимо создавать новое подключение?((

    В общем, мне просто не нравятся в коде строки по типу $this->db->query("запрос");
    Каким образом это заменить, например на CLmysql::query... Но без дополнительных подключений и т.п. вещей... extendets тоже не предлагать)) А то там будет страшная взаимосвязь которую будет сложно менять...
    Или может оставить как есть?
     
  7. Amian

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

    С нами с:
    15 мар 2007
    Сообщения:
    189
    Симпатии:
    0
    Нет, разберись с работой static элементов и паттерном singleton.

    Указатель на указатель это нормальное явление в ООП. Может тебе вообще не нравится программирование или ООП в частности? ~~
     
  8. Ti

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

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    Фишки getInstance:
    - инициализация объекта происходит в getInstance на первом получении объекта
    - объет создастся только при необходимости

    Не используя getInstance нужно заранее инициализировать объекты (которые возможно и не нужны будут - тот же CLReport)

    Не обязательно делать db членом вашего объекта:
    PHP:
    1. <?
    2. CLmysql::getInstance()->query($sql);
    3.  
    4. // или
    5.  
    6. $db = CLmysql::getInstance();
    7. $db->query($sql);
    8.  
     
  9. kagerr

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

    С нами с:
    20 май 2008
    Сообщения:
    17
    Симпатии:
    0
    Amian, Нет, я просто хочу, чтобы код был как можно более удобно читаем... Типа забочусь о будущих поколениях... Чем больше "->", тем больше на мой взгляд запутанность))
     
  10. kagerr

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

    С нами с:
    20 май 2008
    Сообщения:
    17
    Симпатии:
    0
    Ну вот теперь более менее разобрался. Спасибо
     
  11. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    $a->b->c->d() - это извращение.
    зачем в классах хранить классы в которых классы?
    это, скорей всего, ошибки проектирования модели.

    а уж $a->db->query() легко делается через синглетон

    $db = MySQL::GetInstance();
    $db->Query();

    впрочем об этом уже писали и не безосноватльно.
     
  12. kagerr

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

    С нами с:
    20 май 2008
    Сообщения:
    17
    Симпатии:
    0
    Если не сложно, то, пожалуйста, помогите вот с таким вопросом:
    конструктор mysql
    PHP:
    1. /**
    2.      * конструктор
    3.      *
    4.      * @param string $host - хост
    5.      * @param string $login - логин
    6.      * @param string $pass - пароль
    7.      * @param string $database - БД
    8.      */
    9.     function __construct($host,$login,$pass,$database)
    10.     {
    11.         $this->host=$host;
    12.         $this->login=$login;
    13.         $this->passwd=$pass;
    14.         $this->database=$database;
    15.        
    16.     }
    В BeforeLoad.php (то, что перед загрузкой страницы сайта) пишу следующее:

    PHP:
    1. $db = new CLmysql('localhost','root','','CMS');//Класс БД
    2. $db->connect();
    3. $as=CLmysql::getInstance();
    4. $as->query('asdf'); - на это он говорит, что нет подключения к серверу((...
    Следовательно, если сделать connect, то будет новое подключение, а то не хорошо...
    getInstance - такой же, как и в примере здесь...
    Я понимаю, что что-то не понимаю, но что именно не понимаю - не понимаю...
     
  13. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Что метод возвращает? Новый экземпляр?

    Нужно примерно так сделать:
    PHP:
    1. public function connect($host, $login, $pass, $database) {
    2.     // ...
    3. }
    и уже затем:
    PHP:
    1. CLmysql::getInstance()->connect('localhost', 'root', '','CMS');
    2. $as = CLmysql::getInstance();
    3.  
     
  14. Amian

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

    С нами с:
    15 мар 2007
    Сообщения:
    189
    Симпатии:
    0
    Не всегда - Dependency Injection тому подтверждение :wink: Да и при чём здесь классы в классах ? Хранить ссылки на объекты, находящиеся в определённом состоянии, в других объектах, это нормально. Ели понадобится, могу хранить хоть целую коллекцию объектов и не считаю это дурным тоном :shock:
     
  15. Ti

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

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
    kagerr

    код подключения к базе данных в BeforeLoad.php не нужен:
    PHP:
    1. <?
    2. class CLmysql {
    3.     static private $_instance;
    4.  
    5.  
    6.     /**
    7.      * @return CLmysql
    8.      */
    9.     static function getInstance()
    10.     {
    11.         if (is_null(self::$_instance)) {
    12.             // инициализация при первом получении объекта
    13.             $config = CLconfig::getInstance()->get('db');
    14.             self::$_instance = new self($config['host'], $config['login'], $config['pass'], $config['database']);
    15.             self::$_instance->connect();
    16.         }
    17.         return self::$_instance;
    18.     }
    19.  
    20.  
    21.     /**
    22.      * @param string $host - хост
    23.      * @param string $login - логин
    24.      * @param string $pass - пароль
    25.      * @param string $database - БД
    26.      */
    27.     function __construct($host,$login,$pass,$database)
    28.     {
    29.         $this->host=$host;
    30.         $this->login=$login;
    31.         $this->passwd=$pass;
    32.         $this->database=$database;
    33.  
    34.     }
    35.  
    36.     //..
    37. }
    Это лишь пример использования getInstance.
    Есть минимум одна проблема при использовании кода выше: нужно будет помнить ключи конфигурации.

    Решить ее можно написав интерфейс для конфигурации к базе данных и обязав конфигурацию сайта возращать объект с этим интерфейсом.
     
  16. kagerr

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

    С нами с:
    20 май 2008
    Сообщения:
    17
    Симпатии:
    0
    Ну теперь совсем все ясно стало! Спасибо! Теперь даже не просто ясно, но еще и работает))