Основы PHP
  Что такое PHP?
  Возможности PHP
  Преимущества PHP
  История развития
  Что нового в PHP5?
  «Движок» PHP
  Переход на PHP 5.3
New Переход на PHP 5.6
  Введение в PHP
  Изучение PHP
  Основы CGI
  Синтаксис PHP
  Типы данных PHP
  Переменные в PHP
  Константы PHP
  Выражения PHP
  Операторы PHP
  Конструкции PHP
  Ссылки в PHP
  PHP и ООП
  Безопасность
  Функции PHP
  Функции по категориям
  Функции по алфавиту
  Стандартные функции
  Пользовательские
  PHP и HTTP
  Работа с формами
  PHP и Upload
  PHP и Cookies
  PHP и базы данных
  PHP и MySQL
  Документация MySQL
  Учебники
  Учебники по PHP
  Учебники по MySQL
  Другие учебники
  Уроки PHP
  Введение
  Самые основы
  Управление
  Функции
  Документация
  Математика
  Файлы
  Основы SQL
  Дата и время
  CURL
  Изображения
  Стили
  Безопасность
  Установка
  Проектирование БД
  Регулярные выражения
  Подготовка к работе
  Быстрый старт
  Установка PHP
  Установка MySQL
  Конфигурация PHP
  Download / Скачать
  Скачать Apache
  Скачать PHP
  Скачать PECL
  Скачать PEAR
  Скачать MySQL
  Редакторы PHP
  Полезные утилиты
  Документация
  PHP скрипты
  Скачать скрипты
  Инструменты
  PHP в примерах
  Новости портала
 Главная   »  Сборник статей
 
 

Абстрактные классы БД

Автор: Дмитрий Лебедев

Классы, позволяющие работать с разными базами данных через один стандартный набор функций. Полезны при смене базы данных и работе с несколькими БД одновременно.

Тема эта регулярно всплывает в форуме. Собственно, зачем они нужны, эти абстрактные классы баз данных? Большинство сайтов по-хорошему обойдутся и без таких средств унификации. Они работают либо без базы, либо на MySQL, чего для большей части проектов вполне достаточно. Да, да! Достаточно! Когда нагрузки возрастут, вот тогда купят и поставят Оракл, а чтобы скрипты не переписывать, пусть пользуются абстрактными классами. :) Про бесплатные и фирменные базы данных разговор отдельный, грозит превратиться в пустой флейм (а конференциях именно этим все и заканчивается), поэтому не буду его продолжать.

Абстрактные классы позволяют разработчикам писать код без оглядок на то, какая база данных стоит — только на ее возможности и особенности работы. Очень полезно, если работа идет с несколькими базами одновременно (не надо вспоминать, например, что писать: mysql_fetch_array или OCIFetchInto). Смена базы данных тоже многократно облегчится — надо будет всего лишь изменить тип базы в инициализации объекта. Разумеется, все эти красивые вещи оборачиваются большей ресурсоемкостью программ.

Сразу отмечу, что, первое, эти классы я нашел не в каких-либо дебрях сети, а прямо "на поверхности" — hotscripts.com. И второе — написать свой собственный класс — не проблема. И, конечно же, всех классов не опишешь, поэтому если вы считаете, что я пропустил здесь что-то полезное и хорошее, пишите.

Немного о схеме работы с абстрактными классами.

Нормальная схема — это два класса: соединение с базой и результат запроса. В принципе, идентификатор результата запроса можно было держать и внутри объекта БД (например в массиве результатов), но порядка и удобства ради результаты вынесены в отдельный класс.

Итак, найдено пять классов. Описываю в порядке убывания удобства (удобства на мой взгляд).

AdoDB (по имеющимся сведениям — переписанный в php из asp)

Самый расписанный, самый документированный. Есть примеры использования. А оно достаточно простое. Настраиваете в файле adodb.inc.php параметры базы данных, которые будут использоваться по умолчанию. А можно и не настраивать.

Пример из документации:

include("adodb.inc.php");
ADOLoadCode('mysql');
$db = NewADOConnection();
$db->Connect("localhost", "root", "password", "mydb");
$result = $db->Execute("SELECT * FROM employees");
if ($result === false) die("failed");
while (!$result->EOF) {
  for ($i=0, $max=$result->FieldCount(); $i < $max; $i++)
    print $result->fields[$i].' ';
  $result->MoveNext();
  print "<br>
";
  }

Если нужна база не MySQL, а Oracle, меняем вторую строку на

ADOLoadCode('oracle');

Программа сама подключает функцией include_once файл с классом для нужной базы данных.

Поддержка разных баз осуществляется через дочерние классы.

В общем, все работает и пишется хорошо, и требования тоже "хорошие": объем подключаемого кода для БД MySQL равняется 34 килобайтам кода. Для справки: код для этого сайта включая класс шаблона и сами шаблоны "весит" 66 килобайт.

DAC (Database access class).

В использовании — примерно то же, что и AdoDB. Только в "комплекте" нет руководства. :) Разные базы поддерживаются дочерними классами, которые, насколько я понял, подключаются автоматически. Но здесь функций для выполнения запроса несколько — select, insert, update и execute. Не знаю, может, это и удобнее с точки зрения обработки результата, но писать программы по моим прикидкам не будет ни удобнее, ни сложнее (по крайней мере, мне не приходилось сталкиваться с ситуацией, когда тип запроса выбирался в зависимости от ситуации).

class.DBI (Database independent class, говорят, что переписан с Perl-овой версии).

Описано хорошо, но на сайте. Функции разделены, но на две (выборка и остальные запросы). Чтобы достать из архива какие-либо файлы, надо проявить хорошую смекалку. Потому что архив не распаковывается — там в именах файлов двоеточия, и система грязно ругается. Заходим в файл class.DBI-....tgz, копируем оттуда в нужную директорию файл class.DBI-0.3.8.tar и открываем его в UltraEdit. Народным методом copy/paste достаем фрагмент кода под нужную базу. Фуф!

Muze Abstract DB.

В отличие от предыдущих классов здесь запрос отправляется в базу конструктором класса запроса. В одном из классов нашел ошибку — вместо str_replace используется ereg_replace.

DIOW (Database independent object wrapper).

А вот этим классом настоятельно не советую пользоваться. Разделение на разные базы сделано самым глупым способом — если переменная с типом базы, и такая конструкция:

if ($database_type==1) {
  ...
  }
elseif ($database_type==2) {
  ...
  };

А в ней — самое страшное. Попробуйте найти это сами.

if ($database_type==2) {
  $this->my_temp_resultID = mysql_query($someSQL, $this->my_connection);
  $this->my_temp_result_object->numrows = mysql_num_rows($this->my_temp_resultID);
  $this->my_temp_result_object->numcols = mysql_num_fields($this->my_temp_resultID);

  // fill column_names from resultset
  for ($j=0; $j < $this->my_temp_result_object->numcols; $j++) {
    $this->my_temp_result_object->column_name[$j] = 
	mysql_fieldname($this->my_temp_resultID, $j);
    };

  // fill data elements from resultset
  for ($i=0; $i < $this->my_temp_result_object->numrows; $i++) {
    $x = mysql_fetch_row($this->my_temp_resultID);
    for ($j=0; $j < $this->my_temp_result_object->numcols; $j++) {
      $this->my_temp_result_object->element[$i][$j] = $x[$j];
      };
    };

  return $this->my_temp_result_object;
  mysql_free_result($this->my_temp_resultID);
  };

Перед return есть два вложенных цикла, которые тупо берут данные из базы и скидывают их в массив. Конечно же, потом с этим массивом делать можно что угодно, "хоть веревки вейте, хоть ездовую собаку делайте", но это стоит дополнительной занимаемой памяти.

Конечно же, иногда требуется произвести операцию, которая не по силам базе данных, но это один случай из ста. В остальных же нужно просто получать данные и выводить их в документ. При этом сразу после вывода массив строки заменяется на новый, почти такой же. Здесь же этого не происходит.

Тут, конечно, мне можно возразить, мол, сам шаблонами пользуешься, и до конца держишь все в переменной (финал моих скриптов такой: $root->ugh(); — это выводится готовый документ :). Ну, шаблоны — это совсем другое дело. А если я прикручу этот класс к своим шаблонам или к другому скрипту, в котором держать все данные в массиве не нужно, памяти будет требоваться еще больше.

Если же кому-то нужно именно скидывать в один массив все результаты запроса, пользуйтесь другими классами — всего-то четыре строки своего кода.

К тому же, как вы понимаете, освобождения результата в конце функции не произойдет, потому что команда на завершение работы функции — return — уже дана. Если скрипт, который вызывает несколько "хороших" запросов, одновременно вызовет много пользователей, ой, как плохо станет серверу!

 
 » Обсудить эту статью на форуме

 
 Сборник статей 
 Содержание раздела 
Есть еще вопросы или что-то непонятно - добро пожаловать на наш  форум портала PHP.SU 
 

 
Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS