Работа с базами данных с использованием класса ADODB

Maxim Matyukhin

Содержание
  1. Пару слов об ADODB
  2. Установка
  3. Примеры использования
  4. Особенности
  5. ADODB & PEAR
  6. Заключение

1. Пару слов об ADODB

Для начала, скажу что статья рассчитана на программистов, имеющих опыт работы с СУБД, а не на начинающих пхпешников. Я предполагаю, что вы знакомы с PHP, ОПП, SQL и имеете опыт разработки web-приложений.

ADODB - это класс доступа к базам данных, написанный на PHP.
Он позволяет с легкостью переносить скрипты под использование различных СУБД. Например если бы вы не использовали класс доступа к БД и вам нужно было бы скрипты, работающие с mysql, перевести под работу с PostgreSQL, то вам пришлось бы

Если бы вы использовали класс доступа к БД, то вам скорее всего не пришлось бы менять php-код (только в одном месте указали бы, что используете postgresql) и изменить SQL-запросы (хотя иногда и это не понадобилось бы).
Я намеренно в этом описании использовал фразу "класс доступа к БД", поскольку ADODB - не единственный подобный класс. Наиболее известные конкуренты: Многие пишут такие классы сами, но я не сторонник изобретения велосипедов.
Противники таких массивных классов, как ADODB или Pear::DB утверждают, что их использование плохо сказывается на производительности. Да, производительность падает и это вполне логично. НО:
От себя могу добавить, что многие из написанных мною сайтов используют ADODB и проблем с производительностью не имеют.

2. Установка
Здесь все просто.
Скачайте с http://php.weblogs.com/adodb архив и распакуйте его (например в папку ./adodb)
Все, класс готов к использованию.
Можете еще скачать и php-extension, но я его использовать не пробовал
Чтобы использовать класс, вам необходимо включить (include) файл ./adodb/adodb.inc.php

3. Примеры использования
Пример 1

<?
// подключаем класс
include_once("adodb/adodb.inc.php");

// указываем тип БД
$conn = &ADONewConnection('mysql');
// соединяемся с БД
$conn->Connect('localhost', 'user', 'password', 'db_name');
// режим отладки - включен (true)
$conn->debug = true;
$conn->setFetchMode(ADODB_FETCH_ASSOC);
?>

Данный пример демонстрирует подключение к БД. В строке
<? $conn = &ADONewConnection('mysql'); ?>

создается объект соединения с базой данных. Именно через поля и методы данного объекта и будет в дальнейшем вестись работа с базой данных.
Что касается режима отладки, то по умолчанию он выключен. При включенном режиме отладки на экран броузера будут выводиться SQL-запросы и тексты ошибок (если такие были). Очень упрощает процесс написания и отладки скриптов.
Метод $conn->setFetchMode() - указывает, каким образом данные о записях будут записаны в массив - будет ли это ассоциативный массив, или простой нумерованный или и тот и другой. Ей нужно установить одно из значений (0, 1, 2, 3). Для пояснений приведу код из исходников adodb:
<?
   define
('ADODB_FETCH_DEFAULT',0);
   
define('ADODB_FETCH_NUM',1);
   
define('ADODB_FETCH_ASSOC',2);
   
define('ADODB_FETCH_BOTH',3);
?>

Судя по исходникам ADODB_FETCH_DEFAULT == ADODB_FETCH_BOTH

Теперь сделаем запрос к БД:


<?
// делаем запрос к БД
$res = $conn->Execute("SELECT id, title, description FROM tab");
// если по запросу найдены записи в таблице
if ($res && $res->RecordCount() > 0) {
   
// выводим эти записи в цикле
   
while (!$res->EOF) {
      echo
"ID = ".$res->fields['id']."\n";
      echo
"title = ".$res->fields['title']."\n";
      echo
"description".$res->fields['description'];
      
// переходим к следующей записи
      
$res->MoveNext();
   }
}
?>

Вот простейший пример запроса к БД.
Метод $conn->Execute() выполняет запрос к базе данных и возвращает множество записей (recordset).
Множество записей (recordset) - в ADODB является отдельным объектом, который имеет свои поля и методы для работы с полученными записями. Некоторые из них использованы в данном примере.
Метод $conn->Execute() - может быть использован для любых запросов:
<?
// делаем вставку строки
$conn->Execute("INSERT INTO tab(name, value) VALUES ('name', 'ha ha ha')");
// получаем идентификатор вставки
// аналог mysql_insert_id();
$id = $conn->Insert_ID();

$conn->Execute("DELETE FROM tab WHERE id = ".$id);
?>

Опишу еще некоторые полезные методы класса AdoConnection:
4 Особенности
Думаю этот раздел будет наиболее интересен программистам.
4.1 Постраничный вывод и ограничение SELECT-запросов
Вообще-то не все базы данных умеют делать запросы типа: SELECT * FROM tab LIMIT 0, 10
а все те, которые умеют, делают это по разному:
MySQL:
SELECT * FROM tab LIMIT 0, 10
PostgreSQL:
SELECT * FROM tab OFFSET 0, LIMIT 10
FireBird:
SELECT FIRST 10 SKIP 0 * FROM tab
Класс adodb сам может делать ограниченные выборки, составляя правильные SQL-запросы под указанную БД, поддерживающую лимитированные SELECT-запросы
<? $res = $conn->SelectLimit("SELECT * FROM tab", 10, 0); ?>

Метод $conn->SelectLimit() сам построит правильный SQL-запрос
На основе этого метода в ADODB работают функции для постраничной выборки:
<?
// определяем текущую страницу
$start = max(1, intval($_GET['start']));
// количество записей на странице
$rows_per_page = 10;
$res = $conn->PageExecute("SELECT * FROM tab", $rows_per_page, $start);

// получаем найденное количество записей
$records_amount = $res->MaxRecordCount();
?>

Метод $conn->PageExecute() кроме простого LIMIT-запроса делает автоматически еще и запрос типа:
SELECT COUNT(*) FROM tab
Таким образом он сам узнает, сколько всего по данному запросу найдено строк. Это количество можно узнать с помощью метода:
$res->MaxRecordCount();
Также для управления постраничным выводом есть следующие методы:
 
4.2 Генерирование INSERT/UPDATE запросов
Для начала пример:
<?
// пример генерирования INSERT-запроса

// массив, который нужно вставить в таблицу
$frm = array("field1"=>"value1", "field2"=>"value2");
// делаем пустой запрос
$res = $conn->Execute("SELECT * FROM tab WHERE id = -1");
// формируем SQL-запрос
$sql = $conn->GetInsertSQL($res, $frm);
// выполняем запрос
$conn->Execute($sql)

// пример генерирования UPDATE-запроса

// получаем данные о строке, которую нужно обновить
$res = $conn->Execute("SELECT * FROM tab WHERE id = 17");
$sql = $conn->GetUpdateSQL($res, $frm);
// выполняем запрос
$conn->Execute($sql)
?>

Так вот идея в том, чтобы все данные, которые нужно вставить записать в ассоциативный массив. Сделать запрос к БД чтобы получить имена полей таблицы и сконструировать SQL-запрос по этим данным.
Уверен, что будет много противников этого метода (мол лишний SQL-запрос к БД делать), но мне эти функции кажутся очень удобными.
 
4.3 Работа с транзакциями
Ну это вообще сказка :). Вот пример из мануала:
<?
   $conn
->StartTrans();
   
$conn->Execute("update table1 set val=$val1 where id=$id");
   
$conn->Execute("update table2 set val=$val2 where id=$id");
   
$conn->CompleteTrans();
?>

Метод $conn->CompleteTrans(); сам проверит, были ли ошибки и если так - сделает откат.
ADODB имеет еще и другие функции для работы с транзакциями, но они устарели и разработчики ADODB рекомендуют использовать этот вариант.

 
4.4 Последовательности
Часто при работе с таблицами каждой записи нужно присвоить уникальный идентификатор, который потом используется в качестве первичного ключа. Но не все СУБД поддерживают такую возможность. ADODB эмулирует эту возможность почти для всех СУБД. На практике это выглядит примерно так:
<?
   $uid
= $conn->GenID('site_users');
   
$conn->Execute("INSERT INTO site_users(uid, login, password) VALUES(".$uid.", '$login', '$password')");
?>

Метод $conn->GenID() создает последовательность site_users (если она до этого не была создана) и возвращает значение на единицу больше чем текущее значение последовательности.
 
4.5 Кеширование запросов
ADODB поддерживает серверное кеширование запросов. Суть в том, что при первом выполнении запроса его результаты заносятся в кеш-файл. При последующем таком же запросе (если кеш-файл не устарел) данные будут браться из файла.
Честно говоря, мне не нравится метод, которым они производят кеширование (по-моему они слишком уж универсальным сделали его) и предпочитаю делать кеширование своими руками.
Если вас все-таки интересует кеширование, то работает оно так:
<?
   $ADODB_CACHE_DIR
= '/tmp/ADODB_cache';
   
$rs = $conn->CacheExecute('SELECT * FROM tab');
?>

По умолчанию время жизни кеш-файлов - 1 час. Это время можно изменить 2-мя путями:
<?
   $conn
->cacheSecs = 24*3600 // 24 часа
   
$rs = $conn->CacheExecute('SELECT * FROM tab');

   
// или так:
   // время жизни кеша может задаваться первым параметром
   // метода CacheExecute
   
$rs = $conn->CacheExecute