Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: ООП и MySQLi
 
 автор: Sfinks   (11.11.2012 в 09:48)   письмо автору
 
 

Даже не знаю как правильно описать проблему....

Что-то я не пойму, как удобнее организовать подключение к БД?

Сейчас структура программы вкратце такая:
Есть класс MySQLiX - наследник MySQLi с несколькими доп.функциями.
Все обращения к программе идут через index.php, в котором в самом начале подключается config.php, в котором производятся настройки внутренних переменных и констант, и выполняется подключение к БД, т.е. создается экземпляр класса MySQLiX.

Проблема в том, что получается, что без специальных костылей, подключение не доступно внутри всех остальных классов.
Сейчас это решено так: все используемые классы, в которых может потребоваться подключение к БД являются наследниками класса base, в конструкторе которого прописано:
$this->db = &$GLOBALS[DB_LINK];
, где DB_LINK -константа содержащая имя переменной, содержащей класс MySQLiX.

В результате во всех классах ЕСТЬ переменная с экземпляром класса БД.... Но как-то это мне кажется черезодноместно....
Особенно раздражает print_r() какого-нибудь класса, который имеет свойства -объекты других классов-наследников base.... Получается я в каждом классе и подклассе и подподклассе вижу по экземпляру MySQLiX.
Понятно, что экземпляр на самом деле один, а все остальное - ссылки на него. Но очень не красиво.

Как-то можно сделать, чтоб оно само везде было доступно, как при использовании mysql_connect() и mysql_query() ?

  Ответить  
 
 автор: Igorek   (11.11.2012 в 15:18)   письмо автору
 
   для: Sfinks   (11.11.2012 в 09:48)
 

Для таких случаев, насколько я знаю, и используется паттерн синглтон. Т.е. в любом месте, где необходимо использовать класс MySQLiX, вызываем что-то вроде:

$db = MySQLiX::instance();

а по поводу
> В результате во всех классах ЕСТЬ переменная с экземпляром класса БД.... Но как-то это мне кажется черезодноместно....
по-моему, это стандартная практика - включение экземпляра одного класса в другой. Только не через глобальное пространство имен, а через синглтон, как я уже говорил. В конструкторе:
$this->db =MySQLiX::instance();

Я бы так сделал, во-всяком случае )

  Ответить  
 
 автор: cheops   (11.11.2012 в 18:41)   письмо автору
 
   для: Sfinks   (11.11.2012 в 09:48)
 

Это нормально... более того, бывает еще и рекурсивные зацикливания, в этом смысл ссылок на объекты, объект один, но доступен везде и под нужным интерфейсом.

>Как-то можно сделать, чтоб оно само везде было доступно, как при использовании mysql_connect
>() и mysql_query() ?
Перегрузка специальных методов __call() или __get() вам не подойдет? Можно было бы сделать так, что первое обращение к методу db() или свойству db отслеживалось бы в __call() или __get(), где бы и создавалась бы ссылка на $GLOBALS[DB_LINK].

PS Кстати, если в $GLOBALS[DB_LINK] объект, а не дескриптор, то & не нужно.

  Ответить  
 
 автор: Sfinks   (11.11.2012 в 23:03)   письмо автору
 
   для: cheops   (11.11.2012 в 18:41)
 

А не могли бы Вы кодом показать? Что-то я не соображу.

> PS Кстати, если в $GLOBALS[DB_LINK] объект, а не дескриптор, то & не нужно.
А это на что-то влияет? В смысле хуже становится как-то?
На сколько я понимаю, вы о том, что при присваивании переменной экземпляра класса, php сам создает указатель на этот класс.
Но если я ему явно указываю что это указатель, он же не создаст указатель на указатель?
(это просто теоретический вопрос)

  Ответить  
 
 автор: cheops   (12.11.2012 в 21:41)   письмо автору
 
   для: 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 используется только при вызове функций и только в случае базовых типов (когда требуется побочный эффект).

  Ответить  
 
 автор: Sfinks   (12.11.2012 в 23:44)   письмо автору
 
   для: cheops   (12.11.2012 в 21:41)
 

publci - что-то итальянское похоже =)

Получается, что в принципе ничего не изменится. Разница лишь в том, что у меня переменная $db доступна сразу, в наследство от класса base, а в вашем варианте она предоставляется по требованию.

Но т.к. от класса base у меня наследуются лишь классы, которые без БД жить не могут, в результате в print_r() ничего не изменится. Жаль.

Большое спасибо =)

  Ответить  
 
 автор: Igorek   (13.11.2012 в 07:52)   письмо автору
 
   для: 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 пользовать:
<?php echo $object;

  Ответить  
 
 автор: Sfinks   (13.11.2012 в 23:30)   письмо автору
 
   для: Igorek   (13.11.2012 в 07:52)
 

Интересно.... Но у большинства __toString задействован в работе. Так что для меня не вариант.

  Ответить  
 
 автор: Giga   (13.11.2012 в 18:16)   письмо автору
 
   для: cheops   (12.11.2012 в 21:41)
 

А как с PDO вставить в другие классы?
Я делаю вне классов
$db = new PDO();
Потом внутри каждого метода классов, где мне нужно соединение вставляю global $db;
Может есть более простое решение, которое позволит хотя бы вставить соединение внутрь класса без вставки в каждый метод?
Я так понимаю можно конечно организовать новый метод внутри класса, скажем
function db()
{
return new PDO();
}
и потом везде внутри класса использовать $this->db? Правильно ли это и как оно будет сочетаться с $db = new PDO(); вне класса?

  Ответить  
 
 автор: Sfinks   (13.11.2012 в 23:32)   письмо автору
 
   для: Giga   (13.11.2012 в 18:16)
 

> Может есть более простое решение, которое позволит хотя бы вставить соединение
> внутрь класса без вставки в каждый метод?

Прочитайте первый пост в этой теме.

  Ответить  
 
 автор: hk416   (14.11.2012 в 14:38)   письмо автору
 
   для: Sfinks   (13.11.2012 в 23:32)
 

Мужики мне это вопрос тоже интересен, просто почему бы создание нового соединения, тобишь создания нового объекта класса БД, просто не запихнуть в конструктор, тех классов которыми вы пользуетесь. Просто у вас есть написанные классы, по классификации MVC это контроллер,в этих классах конструкторы классов.

  Ответить  
 
 автор: Sfinks   (14.11.2012 в 17:23)   письмо автору
 
   для: hk416   (14.11.2012 в 14:38)
 

Потому что тогда у вас будет куча одинаковых соединений (новое в каждом объекте класса), что, как минимум, не желательно.

А к первому посту я вас направил, не потому что вы не в тему, а потому что там есть ответ на вопрос, как сделать, чтоб не писать каждый раз global $db;

  Ответить  
 
 автор: hk416   (14.11.2012 в 19:33)   письмо автору
 
   для: Sfinks   (14.11.2012 в 17:23)
 

А куча соединений создаваться не будет, они буду заменять друг друга, так как используется объект класса с одним и тем же названием. Просто здесь вопрос в том что как я понял, нужно сделать так что бы писать как можно меньше кода.

  Ответить  
 
 автор: Sfinks   (15.11.2012 в 09:49)   письмо автору
 
   для: hk416   (14.11.2012 в 19:33)
 

> Просто здесь вопрос в том что как я понял, нужно сделать так что бы писать как можно меньше кода.
Не правильно поняли. Вопрос был в том, как получать меньше ненужной дублирующейся информации от сервера. Вопрос минимизации кода был решен изначально.

> А куча соединений создаваться не будет, они буду заменять друг друга, так как
> используется объект класса с одним и тем же названием.

Хрен редьки не слаще.
Представьте, что у вас есть объект ПРАЙС, у него есть свойство ГРУППЫ ТОВАРОВ, которое является массивом объектов ГРУППА, у каждого из которых есть свойство ТОВАРЫ, которое является массивом объектов ТОВАР.
А в прайсе 10 групп по 100 товаров в каждой.
И каждому из перечисленных объектов нужно для загрузки свойств подключиться к базе.
Вы чтобы загрузить весь прайс будете подключаться к базе 1011 раз?

  Ответить  
 
 автор: hk416   (15.11.2012 в 10:34)   письмо автору
 
   для: Sfinks   (15.11.2012 в 09:49)
 

Для этого существует проверка, существует ли объёкт ))))

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования