Здравствуйте. Я вот тут думу думаю... Если не сложно, то поделитесь своими идеями по следующему вопросу: Есть разные самописные классы, например CLmysql (БД), CLreport (отчет об ошибках), CLconfig (установка констант) и другие (их еще куча)... Так вот, мне интересно как лучше поступить, чтобы, например, в классе CLconfig можно было и выполнять запросы mysql и, если возникла ошибка, то отправлять ее в отчет об ошибках... Я делаю на данный момент так (код из CLconfig): Код (Text): function __construct($db,$report) { if (is_a($db, 'CLmysql')){ $this->db=$db; }else{ return(false); } if (!is_a($report,'CLreport')) { return (false); }else{ $this->report=$report; } } extends не пойдет, так как надо наследовать не один, а несколько классов, а делать по типу, что CLreport наследует CLmysql, а CLconfig - CLreport, мне кажется, не очень красиво, так как потом все будет запутано на мой взгляд)) У кого какие предложения по поводу наилучшей реализации подобной фигни?))
PHP: <? // паттерн Singleton class CLmysql { static private $_instance; /** * @return CLmysql */ static function getInstance() { if (is_null(self::$_instance)) self::$_instance = new self; return self::$_instance; } } // в любом месте $mysql = CLmysql::getInstance();
хм... Ну не плохое решение... Я просто по какой-то причине пропустил мимо себя static... Сейчас хоть восполнил эту потерю... Тогда возникает другой вопрос... Что лучше: делать таким образом или просто в классах функции делать static?
Делать все фунцкии в классах static плохо. ООП - Объектно-ориентированное программирование. GetInstance не мешает вам создать другой объект, к примеру соединение с другой базой данной. А если все сделать static это будет проблемно.
Я может не совсем разобрался еще, но столкнулся со следующей проблемой: у меня в констуркторе класса CLmysql идет подключение к БД... Следовательно, при использование getInstance, необходимо создавать новое подключение?(( В общем, мне просто не нравятся в коде строки по типу $this->db->query("запрос"); Каким образом это заменить, например на CLmysql::query... Но без дополнительных подключений и т.п. вещей... extendets тоже не предлагать)) А то там будет страшная взаимосвязь которую будет сложно менять... Или может оставить как есть?
Нет, разберись с работой static элементов и паттерном singleton. Указатель на указатель это нормальное явление в ООП. Может тебе вообще не нравится программирование или ООП в частности? ~~
Фишки getInstance: - инициализация объекта происходит в getInstance на первом получении объекта - объет создастся только при необходимости Не используя getInstance нужно заранее инициализировать объекты (которые возможно и не нужны будут - тот же CLReport) Не обязательно делать db членом вашего объекта: PHP: <? CLmysql::getInstance()->query($sql); // или $db = CLmysql::getInstance(); $db->query($sql);
Amian, Нет, я просто хочу, чтобы код был как можно более удобно читаем... Типа забочусь о будущих поколениях... Чем больше "->", тем больше на мой взгляд запутанность))
$a->b->c->d() - это извращение. зачем в классах хранить классы в которых классы? это, скорей всего, ошибки проектирования модели. а уж $a->db->query() легко делается через синглетон $db = MySQL::GetInstance(); $db->Query(); впрочем об этом уже писали и не безосноватльно.
Если не сложно, то, пожалуйста, помогите вот с таким вопросом: конструктор mysql PHP: /** * конструктор * * @param string $host - хост * @param string $login - логин * @param string $pass - пароль * @param string $database - БД */ function __construct($host,$login,$pass,$database) { $this->host=$host; $this->login=$login; $this->passwd=$pass; $this->database=$database; } В BeforeLoad.php (то, что перед загрузкой страницы сайта) пишу следующее: PHP: $db = new CLmysql('localhost','root','','CMS');//Класс БД $db->connect(); $as=CLmysql::getInstance(); $as->query('asdf'); - на это он говорит, что нет подключения к серверу((... Следовательно, если сделать connect, то будет новое подключение, а то не хорошо... getInstance - такой же, как и в примере здесь... Я понимаю, что что-то не понимаю, но что именно не понимаю - не понимаю...
Что метод возвращает? Новый экземпляр? Нужно примерно так сделать: PHP: public function connect($host, $login, $pass, $database) { // ... } и уже затем: PHP: CLmysql::getInstance()->connect('localhost', 'root', '','CMS'); $as = CLmysql::getInstance();
Не всегда - Dependency Injection тому подтверждение :wink: Да и при чём здесь классы в классах ? Хранить ссылки на объекты, находящиеся в определённом состоянии, в других объектах, это нормально. Ели понадобится, могу хранить хоть целую коллекцию объектов и не считаю это дурным тоном :shock:
kagerr код подключения к базе данных в BeforeLoad.php не нужен: PHP: <? class CLmysql { static private $_instance; /** * @return CLmysql */ static function getInstance() { if (is_null(self::$_instance)) { // инициализация при первом получении объекта $config = CLconfig::getInstance()->get('db'); self::$_instance = new self($config['host'], $config['login'], $config['pass'], $config['database']); self::$_instance->connect(); } return self::$_instance; } /** * @param string $host - хост * @param string $login - логин * @param string $pass - пароль * @param string $database - БД */ function __construct($host,$login,$pass,$database) { $this->host=$host; $this->login=$login; $this->passwd=$pass; $this->database=$database; } //.. } Это лишь пример использования getInstance. Есть минимум одна проблема при использовании кода выше: нужно будет помнить ключи конфигурации. Решить ее можно написав интерфейс для конфигурации к базе данных и обязав конфигурацию сайта возращать объект с этим интерфейсом.