Модераторы: skyboy, MoLeX, Aliance, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Использование класса MySQL во многих классах. Как правильно организовать 
:(
    Опции темы
SqueeZe
Дата 21.12.2007, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 1.10.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 1



Здравствуйте. 

Пишу свою CMS с помощью ООП [PHP + MySQL]. Это уже вторая версия =) (Первую я снес вместе с форматированием С:  smile )
Столкнулся с некоторой сложностью...

Суть в чем. Существует класс LDB для работы с MySQL. В нем всякие полезные методы, подключение[!] итд:

Код

class LDB {
   function __construct()...
   function Select()...
   ...
}


Есть основной класс.

Код

class Index {
   function __construct()...   
   ...
}


И есть множество отдельных подключаемых классов для разных функций. Примером может служить класс Session:

Код

class Session{
   function __construct()...   
   ...
}


Так вот! Мне нужно в классе Session работать с MySQL. 
1. Создавать там экземпляр класса LDB имхо неправильно, тк придется во всех классах где я работаю с базой создавать по экземпляру...  
2. Создать экземпляр в Index. Но тогда придется ведь его передавать по ссылке при создании экземпляра Session. Верно/ неверно?
3. Сделать экземпляр глобальным вне классов.
4. Другие варианты?

Что можете подсказать по этой теме?

Заранее благодарен.
PM MAIL ICQ   Вверх
krundetz
Дата 21.12.2007, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вечный странник
***


Профиль
Группа: Завсегдатай
Сообщений: 1400
Регистрация: 14.6.2007
Где: НН(Сормово)

Репутация: 20
Всего: 69



Вам необходимо разделить клас для работы с базой данных на два один будет устанавливать соединение другой будет выполнять запросы. Вам необходимо сделать класс устанавливающий соединение используя патерн проектирования Одиночка тогда он будет доступен в любом месте кода. Клас исполняющий запросы просто будет использовать клас соединения в своей работе.


--------------------
!цензоры - Хранитель стратегической жидкости
Группа ТГВ
Группа Нижний Новгород
user posted image
PM MAIL   Вверх
SqueeZe
Дата 21.12.2007, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 1.10.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 1



Отличная идея. Спасибо. Щас попробую переписать по такой схеме.
PM MAIL ICQ   Вверх
Mal Hack
Дата 21.12.2007, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: 122
Всего: 261



Как вариант: создаем глобальный объект от классы БД, затем ссылку на него кидаем в свойство (любое) всех других объектов.
PM ICQ   Вверх
SqueeZe
Дата 21.12.2007, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 1.10.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 1



Вот что получилось. Так - решил для галочки отписаться. =)

Код

<?php

    class LDB_Connect 
    {    
        private $hostName = 'localhost';
        private $userName = 'root';
        private $password = '';
        private $databaseName = 'l-cms';    
        
        private $linkId = NULL;
        
        function __construct() 
        {                
            $this->linkId = mysql_connect($this->hostName,$this->userName,$this->password);
            
            if(!$this->linkId) {                
                throw new L_Exception('Не удалось подключиться к серверу MySQL.');                
            }            
            else {                
                if(!mysql_select_db($this->DatabaseName,$this->link_id)) {                
                    throw new L_Exception('Не удалось выбрать базу данных MySQL.');    
                }
                
                return $this->linkId;                        
            }    
            
            @mysql_query("SET NAMES cp1251");                    
        } // __construct        
        
    }
    
    class LDB 
    {            
        private $serverConnected = false;
        private $linkId;
        
        private $query = NULL;
        
        function __construct() 
        {            
            if(!$this->serverConnected) {
                $this->linkId = new LDB_Connect();
                $this->serverConnected = true;
                
                $this->query = new Query();
            }            
        } // __construct
        
        function GetQuerysCount() 
        {    
            return $this->querys->count;            
        } // GetQuerysCount
        
        function GetConfig() 
        {    
            $cfg_arr = NULL;
            $this->querys->Select('all', 'l_config');
            
            while(list($param, $value) = $this->querys->Execute('row')) {
                $cfg_arr[$param] = $value;                
            }            
            return $cfg_arr;                        
        } // GetConfig
    }

?>


Соответственно буду в каждом классе, где нужно пользовать базу создавать экземпляр класса LDB, а уж он сам разберется, надо ли подключаться =)


По поводу варианта от Mal Hack:

Те это будет выглядеть приблизительно так? 

Код

class Index 
{
   private $sqlLink;
   function __construct(&sqll) 
   {
       $this->sqlLink = $sqll;
   }
}

$sql = new MySQL();

$index = new Index($sql);




Это сообщение отредактировал(а) SqueeZe - 21.12.2007, 17:53
PM MAIL ICQ   Вверх
Glip
Дата 21.12.2007, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 473
Регистрация: 30.12.2006

Репутация: 7
Всего: 18



могу оказаться не правым, но разве при такой реализации каждый новый экземляр не класса LDB не будет каждый раз коннектиться?

то есть при создании экземпляра класса каждый раз при вызове new LDB   $this->serverConnected === false.

поправьте если не прав.

Добавлено через 2 минуты и 12 секунд
посмотрите как сказал krundetz, реализацию Singleton


--------------------
user posted image
PM MAIL   Вверх
SqueeZe
  Дата 21.12.2007, 18:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 1.10.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 1



Да. Ты прав. Была у меня такая мыслеха, но я на что то отвлекся... Ща покумекаю. Статичным его что ли сделать?

Добавлено через 5 минут и 53 секунды
Код

<?php

    include_once('query.class.php');

    class LDB_Connect 
    {    
        private $hostName = 'localhost';
        private $userName = 'root';
        private $password = '';
        private $databaseName = 'l-cms';    
        
        private $linkId = NULL;
        
        function __construct() 
        {                
            $this->linkId = mysql_connect($this->hostName,$this->userName,$this->password);
            
            if(!$this->linkId) {                
                throw new Exc('Не удалось подключиться к серверу MySQL.');                
            }            
            else {                
                if(!mysql_select_db($this->DatabaseName,$this->link_id)) {                
                    throw new Exc('Не удалось выбрать базу данных MySQL.');    
                }
                
                return $this->linkId;                        
            }    
            
            @mysql_query("SET NAMES cp1251");                    
        } // __construct        
        
    }
    
    class LDB 
    {            
        public static $serverConnected = false;
        private $linkId;
        
        public $Querys = NULL;
        
        function __construct() 
        {            
            if(!LDB::serverConnected) {
                $this->linkId = new LDB_Connect();
                LDB::$serverConnected = true;
                
                $this->Querys = new Query();
            }            
        } // __construct
        
        function GetQuerysCount() 
        {    
            return $this->Querys->count;            
        } // GetQuerysCount
        
        function GetConfig() 
        {    
            $cfg_arr = NULL;
            $this->Query->Select('all', 'l_config');
            
            while(list($param, $value) = $this->Querys->Execute('row')) {
                $cfg_arr[$param] = $value;                
            }            
            return $cfg_arr;                        
        } // GetConfig
        
        function Execute($mode, $add) 
        {
            $this->Querys->Execute($mode, $add);
        }
        
        function Select($fields, $table, $condition) 
        {
            $this->Querys->Select($fields, $table, $condition);
        }
        
        function Update($table, $sets, $condition) 
        {
            $this->Querys->Update($table, $sets, $condition);
        }
        
        function Insert($table, $vals, $names)
        {
            $this->Querys->Insert($table, $vals, $names);
        }
        
        function Delete($table, $condition)
        {
            $this->Querys->Delete($table, $condition);
        }
    }

?>


Вот так вроде будет работать.
PM MAIL ICQ   Вверх
KEM
Дата 21.12.2007, 20:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 152
Регистрация: 28.1.2005

Репутация: нет
Всего: 2



Вот класс который я использую, может понравиться и пригодится кому

Код

<?php

//class.db_Accessor.php
// update by KEM


 if (str_replace('\\', '/', __FILE__) == $_SERVER['SCRIPT_FILENAME']){
     exit('I must be included!');
 }

/*

  $dbo = new Db($db_login, $db_password, $db_ip, $db_name);
       $dba = new DataAccessor('MySQL');
       $db = $dba->getObj($dbo);
   //    $db->setCharset('cp1251');

        $sql = "SELECT * FROM `root` WHERE enabled = TRUE ;";
        $db->Query($sql)


*/
class Db
{
    private $user;
    private $password;
    private $host;
    private $name;

    public function __construct($user, $password, $host, $name)
    {
        $this->user = $user;
        $this->password = $password;
        $this->host = $host;
        $this->name = $name;
    }

    public function getUser()
    {
        return $this->user;
    }
    public function getPassword()
    {
        return $this->password;
    }
    public function getHost()
    {
        return $this->host;
    }
    public function getName()
    {
        return $this->name;
    }
}


/*----------------------------------------------------------------------------*/


abstract class Connection
{
    protected $db;
    protected $connection;

    final public function __construct($db)
    {
        $this->db = $db;
        $this->Open();
    }

    abstract protected function Open();

    final public function getConnection()
    {
        return $this->connection;
    }
}


/*----------------------------------------------------------------------------*/


class MySQLConnection extends Connection
{

    protected function Open()
    {
         $host = $this->db->getHost();
         $pas = $this->db->getPassword();
         $user = $this->db->getUser();
         $name = $this->db->getName();

         if(!$this->connection = @mysql_pconnect($host, $user, $pas)) {
            $this->Errors[]="Не удается установить подключение";
            return FALSE;
        }
         if(! @mysql_select_db($name)) {
                 $this->Errors[]="Не удается выбрать базу данных";
            return FALSE;
        }
    }
}


/*----------------------------------------------------------------------------*/


abstract class DataAccess
{
    protected $db;
    protected $connection;
    protected $result;
    protected $Errors;
    protected $sql;

    final public function __construct($db)
    {
        $this->db = $db;
    }

    abstract public function Query($sql);
    abstract public function setSQL($sql);
    abstract public function getSQL();
    abstract public function getResultCount();
    abstract public function db2Array();
    abstract public function dbRow2Array($num);
    abstract public function dbNumRows();

    final public function getErrors()
    {
        return $this->Errors;
    }
}


/*----------------------------------------------------------------------------*/


class MySQLDataAccess extends DataAccess
{
    public function setSQL($sql)
    {
     $this->sql = $sql;
    }

   public function getSQL()
    {
     return $this->sql;
    }

    public function Query($sql)
    {
        $this->setSQL($sql);
        $con = new MySQLConnection($this->db);
        $this->connection = $con->getConnection();
        if(!$this->result = @mysql_query($sql, $this->connection))
        {
            $this->Errors[]="Не удается выполнить запрос: $sql <br>".mysql_error($this->connection);
            return FALSE;
        }
        else
            return TRUE;
    }

    public function setCharset($charset)
    {
        $sql = "SET NAMES '$charset'";
        $this->Query($sql);
    }

    public function db2Array()
    {
        $array = array();
        while($rows = @mysql_fetch_array($this->result, MYSQL_ASSOC))
        {
            $array[] = $rows;
        }
        return $array;


     }


    public function getResultCount(){
        return mysql_num_rows($this->result);
    }


     public function dbRow2Array($num)
     {
        $num = (int)$num;
        $i=0;
        while($rows = @mysql_fetch_array($this->result, MYSQL_ASSOC))
        {
          if($i === $num)
          {
             $data = $rows;
             break;
          }
          $i++;
        }
        if(count($data)<0)
        {
          $this->Errors[]="Массив строк пуст";
          return FALSE;
        }
        else
            return $this->data;
     }



     public function dbNumRows()
     {
        $numRows = @mysql_num_rows($this->result);
        if($numRows > 0)
             return $numRows;
        else
        {
             $this->Errors[]="Не удается получить число выбранных строк";
             return false;
        }
     }
}


/*----------------------------------------------------------------------------*/


class DataAccessor
{
    private $type;

    public function __construct($type)
    {
        $this->type = $type;
    }

    public function getObj($db)
    {
        switch($this->type)
        {
            case 'MySQL':
                $obj = new MySQLDataAccess($db);
                break;
            case 'MSSQL':
                $obj = new MSSQLDataAccess($db);
                break;
            default:
                $obj = new MySQLDataAccess($db);
      break;
        }
        return $obj;
    }
}
?>


--------------------
Мы растворяем сознание жизни, реальностью стал бешеный ритм...
PM MAIL   Вверх
vasac
Дата 21.12.2007, 22:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1060
Регистрация: 4.5.2006

Репутация: 8
Всего: 36



А вот класс, который я использую — http://pyha.ru/forum/topic/413.0 (совершенно наглая реклама). Тоже может пригодится.
Там же есть одно из возможных решений вашей проблемы (как пример).

Делать же, как вы сейчас придумали одно статичное поле, смысла ноль. Тогда объекты вообще не нужны, делайте тогда весь класс статическим.
PM WWW   Вверх
Mal Hack
Дата 21.12.2007, 22:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: 122
Всего: 261



Да, я имел ввиду именно такую реализацию. С точки зрения оптимальности и ичитаемости лучше всего
.
PM ICQ   Вверх
SqueeZe
Дата 21.12.2007, 23:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 1.10.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 1



Хм. Я вот честно говоря вот чего понять не могу. Зачем использовать такие сложные классы для работы с БД. Ведь вот например, что мне нужно от сего класса:

1. Возможность выполнить запрос с его подсчетом.
2. Удобный доступ к Select Update Delete Insert
3. Фильтрацию запроса от зловредностей всяких =)

И все! Я наверное чайник.. Пришел тут незнающий, руками машу, а толку 0... Я не вижу смысла в сложнейших реализациях. Вот к примеру класс, что предложил тов. KEM: Ну и нахрена мне методы которые запрашивают имя хост пароль итд.. Где я буду этим пользоваться?
PM MAIL ICQ   Вверх
Mal Hack
Дата 22.12.2007, 00:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: 122
Всего: 261



SqueeZe, по хорошему, вам нужно PDO, с учетом последних требований, и небольшая обертка для него, для более тесной интеграции с вашим приложением...
Это наиболее оптимальный вариант уж если говорить, положа руку на сердце..

А потом, простите, как спросили, так вам и ответили...
PM ICQ   Вверх
SqueeZe
Дата 22.12.2007, 01:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 1.10.2007
Где: Санкт-Петербург

Репутация: 1
Всего: 1



Сорри, если немного погорячился. Просто видимо не допонял некоторые моменты. Зеленый я еще. Но нужно искать, думать... Без этого никак [На самом деле люблю комфортные, грамотные и конструктивные общения].

Ну это отступление. Сразу скажу спасибу тов. Mal Hack за оперативные ответы. =)
Долго думал над вашим постом. Не знаю про PDO (уй, щас ногами бить будут, САПОГАМИ smile )...


---------------------------------
Так. С общими принципами PDO разобрался. Вот только где бы пример посмотреть. Для простейшей работы с базой.





Это сообщение отредактировал(а) SqueeZe - 22.12.2007, 01:38
PM MAIL ICQ   Вверх
Mal Hack
Дата 22.12.2007, 01:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: 122
Всего: 261



mysqli - скорее часть PDO, а сам PDO - тот самый класс, который вы сами пишете. Точнеее их там как бы два, один отвечает за выполнение запросов, второй за парсинг данных.
Вот, почитайте: http://ru2.php.net/pdo
Сразу скажу, с полвинка в это не вьехать, сам разбирался что за зверь и что дает двое суток, но копаться в этом стоит.
PM ICQ   Вверх
skyboy
Дата 22.12.2007, 01:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 75
Всего: 260



Цитата(SqueeZe @  22.12.2007,  00:30 Найти цитируемый пост)
Не знаю про PDO

Цитата(SqueeZe @  22.12.2007,  00:30 Найти цитируемый пост)
Предполагаю, что mysqli им является?

товарищ, юзайте поиск! денег за это никто не берет!
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0664 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.