За последние 24 часа нас посетили 63236 программистов и 1738 роботов. Сейчас ищут 898 программистов ...

ОПП передача наследованного объекта

Тема в разделе "Прочие вопросы по PHP", создана пользователем Mr.M.I.T., 5 сен 2008.

  1. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    Короче, начал серьёзно изучать ООП
    На практике сталкнулся с такой проблемой
    Сразу лучше на примере
    PHP:
    1.  
    2. <?
    3. class main extends db_class {
    4.     public $data=false;
    5.     public $cnf=false;
    6.   function __construct($cnf,$data) {
    7.         $this->data=$data;
    8.         $this->cnf=$cnf;
    9.         parent::__construct($cnf,$data);
    10.     }
    11.   function 123123() {
    12.     include "comment.class.php";
    13.     $comment=new comment($this->data,$this->cnf,Объект db_class);
    14.  }
    15. }
    16.  
    17. class comment {
    18. private $db;
    19.     function __construct($cnf,$data,$db) {
    20.       $this->db=$db;
    21.     }
    22. }
    23. ?>
    Вопрос как мне передать классу comment из класса main ранее наследованный класс db_class?
    это тоже не вариант: class comment extends db_class
    придётся создавать ещё одно соединение с БД
    Единственное что приходит в голову это передать $this в классе main но что-то такого я ещё не видел...
     
  2. Dagdamor

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

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    Mr.M.I.T.
    Класс поддержки DB - это вспомогательный класс.
    По идее, от него ничего, кроме более специфических классов для работы с БД, наследоваться не должно.
    Остальные классы должны его использовать, например так:
    PHP:
    1. <?php $data=db_class::query("...");
    или так:
    PHP:
    1. <?php $data=db_class::getInstance()->query("...");
    но уж всяко не $this->query(), иначе у тебя в каждом объекте будет куча ненужного мусора типа ресурса соединения.
     
  3. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    ок, а я статей начитался, там в примерах используют наследование класса для работы с БД....
     
  4. DarkElf

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

    С нами с:
    22 окт 2006
    Сообщения:
    1.632
    Симпатии:
    0
    нее... у меня например указатель соединения - зашит в статическую переменную..
    и метод установки соединения сперва проверяет, а нет ли уже открытого. если есть - юзает его. по логу мускула коннект 1 используется)
     
  5. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Не наследуй класс для работы с БД. Храни в main единственный экземпляр этого класса и передавай его в comment.

    PHP:
    1. <?php
    2. class main {
    3.     private $db;
    4.  
    5.     public function __construct() {
    6.         $this->db = new db_class();
    7.     }
    8.  
    9.     public function comment() {
    10.         $comment = new comment($this->db);
    11.     }
    12. }
    13.  
    14.  
     
  6. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    таг, пеерписал на db_class::
    вылезла проблема
    PHP:
    1.  
    2. <?
    3. class db_class {
    4.        function sql_blabla() {
    5.            return  $this->query('12312312');
    6.       }
    7. }
    8. class main {
    9.      public $data=false;
    10.      public $cnf=false;
    11.    function __construct($cnf,$data) {
    12.          $this->data=$data;
    13.          $this->cnf=$cnf;
    14.          db_class::__construct($cnf,$data);
    15.      }
    16.     function 123123() {
    17.           $sql=db_class::sql_blabla();
    18.    }  
    19.   }
    20.  
    21. ?>
    22.  
    $this->query('12312312');
    метод query ищётся в классе main естественно его там нет, вылазит ошибка
    заменить в db_class все $this на db_class:: нельзя, т.к. есть private св-ва и методы...
     
  7. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    Код (Text):
    1. $this->db = new db_class();
    тоже вариант...
    а что быстрее работает
    db_class::$blabla
    или
    $this->db->blabla
    ?
     
  8. DarkElf

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

    С нами с:
    22 окт 2006
    Сообщения:
    1.632
    Симпатии:
    0
    Sergey89

    чем плох вариант:

    PHP:
    1. <?php
    2. class myvars{
    3. public static $dbh = false;
    4. }
    5. class database{
    6.     public function dbping(){
    7.         if(!myvars::$dbh){
    8.             $dbh = new mysqli();
    9.             myvars::$dbh =& $dbh;
    10.         }
    11.     }
    12. }
    13. class appl extends database{
    14.     public function save(){
    15.         $this->dbping();
    16.         //в результате имеем установленный дескриптор соединения. если он был, то существующий. если не было, то вновь созданный
    17.     }
    18. }
    19. ?>
     
  9. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    DarkElf, а это по сути не тоже самое?
    PHP:
    1.   $this->db = new db_class();
     
  10. DarkElf

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

    С нами с:
    22 окт 2006
    Сообщения:
    1.632
    Симпатии:
    0
    Mr.M.I.T.

    ну, а что мешает и в конструкторе проверять, есть ли соединение. и если есть, то его вернуть, а не новое создавать?
     
  11. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    можно и так, но уж тогда проще ИМХО просто передать классу comment уже созданный объект db_class..
    вопрос в скорости
    всётаки что быстрее работает из 3 предложенных вариантов?
    db_class::blabla
    $this->db->blabla
    или
    вариант DarkElf
     
  12. DarkElf

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

    С нами с:
    22 окт 2006
    Сообщения:
    1.632
    Симпатии:
    0
    Mr.M.I.T.
    а если классов будет не один, два, а хз сколько? на каждую страницу
     
  13. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    а я хз что быстрее
    передавать объект так
    Код (Text):
    1. $comemnt=new comment($this->db);
    2. class comment {
    3.        function __construct($db) {
    4.            $subcomment=new subcomment($db);
    5.        }
    6. }
    или твой вариант, но у тебя мне кажется минусом extends database
    вдруг мне надо другой наследовать...
    а вообще я ещё только только погружаюсь в прекласный мир ОПП PHP5 =)
     
  14. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    DarkElf, это навешивание на класс appl лишнего функционала. Часто, более удачным решением является именно агрегирование, а не наследование.

    PHP:
    1. <?php
    2. class Appl
    3.     public function __construct {
    4.          $this->db = Locator::getDb();
    5.     }
    6. }
    7.  
    8. class Locator {
    9.     private $db;
    10.  
    11.     public function getDb() {
    12.         if (!$this->db) {
    13.             $this->db = $this->createDefaultDbConnection();
    14.         }
    15.  
    16.          return $this->db;
    17.     }
    18.  
    19.     //...
    20. }
     
  15. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    для общего развития, интересует
     
  16. DarkElf

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

    С нами с:
    22 окт 2006
    Сообщения:
    1.632
    Симпатии:
    0
    Sergey89

    тут ведь как.. у меня, где я такой код использую, части методов не нужна база данных. поэтому и не ставлю соединение / проверку соединения с ней в конструктор. а только там, где она нужна.
     
  17. Вльдемар

    Вльдемар Активный пользователь

    С нами с:
    20 май 2006
    Сообщения:
    635
    Симпатии:
    0
    Адрес:
    Белхород
    Я делаю так примерно.
    Где то в конфиге есть строчка

    PHP:
    1.  
    2. <?php
    3. //...
    4. $DB = new class_db();
    5. //...
    6. ?>
    7.  
    И в каждом классе который использует БД
    PHP:
    1.  
    2. <?php
    3. class myclass {
    4. private $DB;
    5. function __construct(){
    6. $this->DB = &$GLOBALS['DB'];
    7. }
    8.  
    9. }
    10. ?>
    11.  
     
  18. Sergey89

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

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Вльдемар, в PHP 5 объект всегда передаётся по ссылке. А использовать $GLOBALS при работе с ООП, как-то не красиво.
     
  19. Вльдемар

    Вльдемар Активный пользователь

    С нами с:
    20 май 2006
    Сообщения:
    635
    Симпатии:
    0
    Адрес:
    Белхород
    ООП не очень хорошо знаю
    Можно тогда так

    PHP:
    1. <?php
    2. class myclass {
    3. private $DB;
    4. function __construct(){
    5. $this->DB = class_bd::GetInstance();
    6. }
    7.  
    8. }
    9. ?>
     
  20. EugeneTM

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

    С нами с:
    19 апр 2008
    Сообщения:
    85
    Симпатии:
    0
    На мой IMHO подход Sergey89 самый правильный.
    По своей сути он делает главное, мух от котлет разводит.

    Ведь что такое link. По сути вещь которая вспомогательная и жить она должна сама по себе. Сегодня я к базе link'уюсь, завтра memcached привинтить захотел, да мало ли что - вплоть до хосты могут разные стать.

    Основной класс ведь не коннектами должен заниматься, а делать только то для чего он создан.
    Вот и пусть link'и отдельный класс делает. А основной в нужном месте его экземпляр параметром получает. Или локатором нужный метод находит. Тут на вкус и цвет и по ситуации смотреть.

    Это конкретно жизнь очень сильно облегчит впоследствии. Статейка правильная на эту тему
    http://wiki.agiledev.ru/doku.php?id=ooad:manage_dependencies_in_php_code
    Там не надо в код вникать. Вводную часть про гниль прочитать, а все остальное можно в двух словах выразить. Главное чтоб классы НЕ зависили друг от друга и как можно меньше знали друг о друге. А все что после введения - это примеры реализации и в каждой ситуации может разный подход оптимальным быть.
     
  21. Dagdamor

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

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    Вльдемар
    Если у тебя класс БД хранится как глобальная переменная, зачем ее копии еще и в каждый объект-то пихать?
    Я бы написал global $DB; и дальше работал с этим объектом напрямую. Гибкое и удобное решение. И хоть это и не главный показатель, по скорости/памяти, наверное, наилучшее.
     
  22. Вльдемар

    Вльдемар Активный пользователь

    С нами с:
    20 май 2006
    Сообщения:
    635
    Симпатии:
    0
    Адрес:
    Белхород
    У меня че то не работало с global $DB, а разбираться было лень.
    Нужно покапаться
     
  23. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    я сделал с локатором =)