|
|
|
| Даже не знаю как правильно описать проблему....
Что-то я не пойму, как удобнее организовать подключение к БД?
Сейчас структура программы вкратце такая:
Есть класс MySQLiX - наследник MySQLi с несколькими доп.функциями.
Все обращения к программе идут через index.php, в котором в самом начале подключается config.php, в котором производятся настройки внутренних переменных и констант, и выполняется подключение к БД, т.е. создается экземпляр класса MySQLiX.
Проблема в том, что получается, что без специальных костылей, подключение не доступно внутри всех остальных классов.
Сейчас это решено так: все используемые классы, в которых может потребоваться подключение к БД являются наследниками класса base, в конструкторе которого прописано:
$this->db = &$GLOBALS[DB_LINK];
| , где DB_LINK -константа содержащая имя переменной, содержащей класс MySQLiX.
В результате во всех классах ЕСТЬ переменная с экземпляром класса БД.... Но как-то это мне кажется черезодноместно....
Особенно раздражает print_r() какого-нибудь класса, который имеет свойства -объекты других классов-наследников base.... Получается я в каждом классе и подклассе и подподклассе вижу по экземпляру MySQLiX.
Понятно, что экземпляр на самом деле один, а все остальное - ссылки на него. Но очень не красиво.
Как-то можно сделать, чтоб оно само везде было доступно, как при использовании mysql_connect() и mysql_query() ? | |
|
|
|
|
|
|
|
для: Sfinks
(11.11.2012 в 09:48)
| | Для таких случаев, насколько я знаю, и используется паттерн синглтон. Т.е. в любом месте, где необходимо использовать класс MySQLiX, вызываем что-то вроде:
$db = MySQLiX::instance();
|
а по поводу
> В результате во всех классах ЕСТЬ переменная с экземпляром класса БД.... Но как-то это мне кажется черезодноместно....
по-моему, это стандартная практика - включение экземпляра одного класса в другой. Только не через глобальное пространство имен, а через синглтон, как я уже говорил. В конструкторе:
$this->db =MySQLiX::instance();
|
Я бы так сделал, во-всяком случае ) | |
|
|
|
|
|
|
|
для: Sfinks
(11.11.2012 в 09:48)
| | Это нормально... более того, бывает еще и рекурсивные зацикливания, в этом смысл ссылок на объекты, объект один, но доступен везде и под нужным интерфейсом.
>Как-то можно сделать, чтоб оно само везде было доступно, как при использовании mysql_connect
>() и mysql_query() ?
Перегрузка специальных методов __call() или __get() вам не подойдет? Можно было бы сделать так, что первое обращение к методу db() или свойству db отслеживалось бы в __call() или __get(), где бы и создавалась бы ссылка на $GLOBALS[DB_LINK].
PS Кстати, если в $GLOBALS[DB_LINK] объект, а не дескриптор, то & не нужно. | |
|
|
|
|
|
|
|
для: cheops
(11.11.2012 в 18:41)
| | А не могли бы Вы кодом показать? Что-то я не соображу.
> PS Кстати, если в $GLOBALS[DB_LINK] объект, а не дескриптор, то & не нужно.
А это на что-то влияет? В смысле хуже становится как-то?
На сколько я понимаю, вы о том, что при присваивании переменной экземпляра класса, php сам создает указатель на этот класс.
Но если я ему явно указываю что это указатель, он же не создаст указатель на указатель?
(это просто теоретический вопрос) | |
|
|
|
|
|
|
|
для: Sfinks
(11.11.2012 в 23:03)
| | Можно ввести закрытую переменную $_db, в которой хранить дескриптор соединения. Перегрузить метод __get() и ловить в нем обращение к свойству db. Если это первое обращение - создавать, если последующие - возвращать.
<?php
...
private $_db;
...
publci function __get($name){
if($name == "db")
if(is_a($this->_db, 'MySQLiX')) return $this->_db;
else{
$this->_db = MySQLiX::instance();
return $this->_db
}
return null;
}
...
?>
| тогда вы сможет просто использовать $this->db ничего предварительно не создаваясь и не задумываясь.
>А это на что-то влияет? В смысле хуже становится как-то?
Нет, хуже не становится, все так как вы написали, просто это вроде как непрофессионально... & в PHP используется только при вызове функций и только в случае базовых типов (когда требуется побочный эффект). | |
|
|
|
|
|
|
|
для: cheops
(12.11.2012 в 21:41)
| | publci - что-то итальянское похоже =)
Получается, что в принципе ничего не изменится. Разница лишь в том, что у меня переменная $db доступна сразу, в наследство от класса base, а в вашем варианте она предоставляется по требованию.
Но т.к. от класса base у меня наследуются лишь классы, которые без БД жить не могут, в результате в print_r() ничего не изменится. Жаль.
Большое спасибо =) | |
|
|
|
|
|
|
|
для: Sfinks
(12.11.2012 в 23:44)
| | может тогда такой костыль: определить __toString в базовом классе, как -то так:
<?php public function __toString()
{
$arr = get_object_vars($this);
unset($arr['db']);
print_r($arr);
return '';
}
|
и при выводе объекта просто print или echo пользовать:
| |
|
|
|
|
|
|
|
для: Igorek
(13.11.2012 в 07:52)
| | Интересно.... Но у большинства __toString задействован в работе. Так что для меня не вариант. | |
|
|
|
|
|
|
|
для: cheops
(12.11.2012 в 21:41)
| | А как с PDO вставить в другие классы?
Я делаю вне классов
$db = new PDO();
Потом внутри каждого метода классов, где мне нужно соединение вставляю global $db;
Может есть более простое решение, которое позволит хотя бы вставить соединение внутрь класса без вставки в каждый метод?
Я так понимаю можно конечно организовать новый метод внутри класса, скажем
function db()
{
return new PDO();
}
и потом везде внутри класса использовать $this->db? Правильно ли это и как оно будет сочетаться с $db = new PDO(); вне класса? | |
|
|
|
|
|
|
|
для: Giga
(13.11.2012 в 18:16)
| | > Может есть более простое решение, которое позволит хотя бы вставить соединение
> внутрь класса без вставки в каждый метод?
Прочитайте первый пост в этой теме. | |
|
|
|
|
|
|
|
для: Sfinks
(13.11.2012 в 23:32)
| | Мужики мне это вопрос тоже интересен, просто почему бы создание нового соединения, тобишь создания нового объекта класса БД, просто не запихнуть в конструктор, тех классов которыми вы пользуетесь. Просто у вас есть написанные классы, по классификации MVC это контроллер,в этих классах конструкторы классов. | |
|
|
|
|
|
|
|
для: hk416
(14.11.2012 в 14:38)
| | Потому что тогда у вас будет куча одинаковых соединений (новое в каждом объекте класса), что, как минимум, не желательно.
А к первому посту я вас направил, не потому что вы не в тему, а потому что там есть ответ на вопрос, как сделать, чтоб не писать каждый раз global $db; | |
|
|
|
|
|
|
|
для: Sfinks
(14.11.2012 в 17:23)
| | А куча соединений создаваться не будет, они буду заменять друг друга, так как используется объект класса с одним и тем же названием. Просто здесь вопрос в том что как я понял, нужно сделать так что бы писать как можно меньше кода. | |
|
|
|
|
|
|
|
для: hk416
(14.11.2012 в 19:33)
| | > Просто здесь вопрос в том что как я понял, нужно сделать так что бы писать как можно меньше кода.
Не правильно поняли. Вопрос был в том, как получать меньше ненужной дублирующейся информации от сервера. Вопрос минимизации кода был решен изначально.
> А куча соединений создаваться не будет, они буду заменять друг друга, так как
> используется объект класса с одним и тем же названием.
Хрен редьки не слаще.
Представьте, что у вас есть объект ПРАЙС, у него есть свойство ГРУППЫ ТОВАРОВ, которое является массивом объектов ГРУППА, у каждого из которых есть свойство ТОВАРЫ, которое является массивом объектов ТОВАР.
А в прайсе 10 групп по 100 товаров в каждой.
И каждому из перечисленных объектов нужно для загрузки свойств подключиться к базе.
Вы чтобы загрузить весь прайс будете подключаться к базе 1011 раз? | |
|
|
|
|
|
|
|
для: Sfinks
(15.11.2012 в 09:49)
| | Для этого существует проверка, существует ли объёкт )))) | |
|
|
|