Короче, начал серьёзно изучать ООП На практике сталкнулся с такой проблемой Сразу лучше на примере PHP: <? class main extends db_class { public $data=false; public $cnf=false; function __construct($cnf,$data) { $this->data=$data; $this->cnf=$cnf; parent::__construct($cnf,$data); } function 123123() { include "comment.class.php"; $comment=new comment($this->data,$this->cnf,Объект db_class); } } class comment { private $db; function __construct($cnf,$data,$db) { $this->db=$db; } } ?> Вопрос как мне передать классу comment из класса main ранее наследованный класс db_class? это тоже не вариант: class comment extends db_class придётся создавать ещё одно соединение с БД Единственное что приходит в голову это передать $this в классе main но что-то такого я ещё не видел...
Mr.M.I.T. Класс поддержки DB - это вспомогательный класс. По идее, от него ничего, кроме более специфических классов для работы с БД, наследоваться не должно. Остальные классы должны его использовать, например так: PHP: <?php $data=db_class::query("..."); или так: PHP: <?php $data=db_class::getInstance()->query("..."); но уж всяко не $this->query(), иначе у тебя в каждом объекте будет куча ненужного мусора типа ресурса соединения.
нее... у меня например указатель соединения - зашит в статическую переменную.. и метод установки соединения сперва проверяет, а нет ли уже открытого. если есть - юзает его. по логу мускула коннект 1 используется)
Не наследуй класс для работы с БД. Храни в main единственный экземпляр этого класса и передавай его в comment. PHP: <?php class main { private $db; public function __construct() { $this->db = new db_class(); } public function comment() { $comment = new comment($this->db); } }
таг, пеерписал на db_class:: вылезла проблема PHP: <? class db_class { function sql_blabla() { return $this->query('12312312'); } } class main { public $data=false; public $cnf=false; function __construct($cnf,$data) { $this->data=$data; $this->cnf=$cnf; db_class::__construct($cnf,$data); } function 123123() { $sql=db_class::sql_blabla(); } } ?> $this->query('12312312'); метод query ищётся в классе main естественно его там нет, вылазит ошибка заменить в db_class все $this на db_class:: нельзя, т.к. есть private св-ва и методы...
Код (Text): $this->db = new db_class(); тоже вариант... а что быстрее работает db_class::$blabla или $this->db->blabla ?
Sergey89 чем плох вариант: PHP: <?php class myvars{ public static $dbh = false; } class database{ public function dbping(){ if(!myvars::$dbh){ $dbh = new mysqli(); myvars::$dbh =& $dbh; } } } class appl extends database{ public function save(){ $this->dbping(); //в результате имеем установленный дескриптор соединения. если он был, то существующий. если не было, то вновь созданный } } ?>
Mr.M.I.T. ну, а что мешает и в конструкторе проверять, есть ли соединение. и если есть, то его вернуть, а не новое создавать?
можно и так, но уж тогда проще ИМХО просто передать классу comment уже созданный объект db_class.. вопрос в скорости всётаки что быстрее работает из 3 предложенных вариантов? db_class::blabla $this->db->blabla или вариант DarkElf'а
а я хз что быстрее передавать объект так Код (Text): $comemnt=new comment($this->db); class comment { function __construct($db) { $subcomment=new subcomment($db); } } или твой вариант, но у тебя мне кажется минусом extends database вдруг мне надо другой наследовать... а вообще я ещё только только погружаюсь в прекласный мир ОПП PHP5 =)
DarkElf, это навешивание на класс appl лишнего функционала. Часто, более удачным решением является именно агрегирование, а не наследование. PHP: <?php class Appl public function __construct { $this->db = Locator::getDb(); } } class Locator { private $db; public function getDb() { if (!$this->db) { $this->db = $this->createDefaultDbConnection(); } return $this->db; } //... }
Sergey89 тут ведь как.. у меня, где я такой код использую, части методов не нужна база данных. поэтому и не ставлю соединение / проверку соединения с ней в конструктор. а только там, где она нужна.
Я делаю так примерно. Где то в конфиге есть строчка PHP: <?php //... $DB = new class_db(); //... ?> И в каждом классе который использует БД PHP: <?php class myclass { private $DB; function __construct(){ $this->DB = &$GLOBALS['DB']; } } ?>
Вльдемар, в PHP 5 объект всегда передаётся по ссылке. А использовать $GLOBALS при работе с ООП, как-то не красиво.
ООП не очень хорошо знаю Можно тогда так PHP: <?php class myclass { private $DB; function __construct(){ $this->DB = class_bd::GetInstance(); } } ?>
На мой IMHO подход Sergey89 самый правильный. По своей сути он делает главное, мух от котлет разводит. Ведь что такое link. По сути вещь которая вспомогательная и жить она должна сама по себе. Сегодня я к базе link'уюсь, завтра memcached привинтить захотел, да мало ли что - вплоть до хосты могут разные стать. Основной класс ведь не коннектами должен заниматься, а делать только то для чего он создан. Вот и пусть link'и отдельный класс делает. А основной в нужном месте его экземпляр параметром получает. Или локатором нужный метод находит. Тут на вкус и цвет и по ситуации смотреть. Это конкретно жизнь очень сильно облегчит впоследствии. Статейка правильная на эту тему http://wiki.agiledev.ru/doku.php?id=ooad:manage_dependencies_in_php_code Там не надо в код вникать. Вводную часть про гниль прочитать, а все остальное можно в двух словах выразить. Главное чтоб классы НЕ зависили друг от друга и как можно меньше знали друг о друге. А все что после введения - это примеры реализации и в каждой ситуации может разный подход оптимальным быть.
Вльдемар Если у тебя класс БД хранится как глобальная переменная, зачем ее копии еще и в каждый объект-то пихать? Я бы написал global $DB; и дальше работал с этим объектом напрямую. Гибкое и удобное решение. И хоть это и не главный показатель, по скорости/памяти, наверное, наилучшее.