PHP5_nachinayushim
.pdfÂ
Использование SQLite
В дистрибутив пятой версии PHP включена библиотека SQLite. Это, по сути, дает поль+ зователям завершенную, поддерживающую языки сценариев серверную систему управле+ ния реляционными базами данных в виде одного бесплатного и простого в использовании инструмента. Как использовать этот инструмент и использовать ли его вообще ++++++ ре+ шать вам. В этом приложении представлена краткая информация, необходимая для то+ го, чтобы включить SQLite в Web+проект. Однако, прежде всего, это приложение пред+ назначено для того, чтобы дать читателю навыки использования инструментов SQLite.
Что такое SQLite?
SQLite представляет собой базовую библиотеку, написанную на C, которая делает встраиваемую машину SQL+баз данных доступной использующим ее приложениям. Конечно, SQLite можно использовать и как автономную систему баз данных ++++++ здесь такой вариант рассматривается, ++++++ но основная ценность технологии SQLite заключа+ ется в том, что ее можно использовать в качестве сервера баз данных для более функ+ ционально развитого приложения, написанного на PHP. SQLite в отличие от MySQL не является клиент+серверной СУРБД, это даже не часть такой системы. SQLite счи+ тывает и записывает данные в локально сохраняемые дисковые файлы, в которых со+ держатся создаваемые и используемые базы данных. Такое определение может пока+ заться очень похожим на определение системы баз данных на основе простых файлов, таких как DBM, однако это не так. SQLite ++++++ вполне завершенная СУРБД со многими функциями, сопутствующими этому понятию, которая также содержит ре+ альную реализацию SQL, основанную на стандарте SQL 92.
SQLite ++++++ детище Д. Ричарда Хиппа (D. Richard Hipp) из Wyrick & Company, Inc., а начиная с декабря 2000 года проект SQLite развивается благодаря усилиям многих энтузиастов. Несмотря на кажущуюся коммерческую направленность SQLite ++++++ бес+ платный продукт, полностью являющийся достоянием общественности и освобож+ дающий пользователей от ответственности, предполагаемой какой+либо лицензией, даже такой либеральной, как GPL.
Использование SQLite 775
Как получить SQLite?
Если при установке PHP SQLite+расширение не было явно отключено, то все, что нужно для написания приложений на основе этой СУБД, уже есть. Для независимых от PHP экспериментов с SQLite можно использовать утилиту командной строки, ко+ торая доступна на странице www.sqlite.org/download.html. Web+сайт SQLite www.sqlite.org/ содержит гораздо больше информации о продукте, чем можно было включить в это приложение; в то же время там не много сказано об использова+ нии SQLite с PHP. Благодаря PHP проект SQLite в скором времени безусловно завою+ ет широкую популярность, пока же наилучшим источником информации по этой теме является сайт PHP www.php.net/.
Почему стоит (или не стоит) использовать SQLite?
Мнения программистов расходятся, поэтому приведенные ниже замечания по SQLite предлагаются не как преимущества или недостатки, а скорее как факты, кото+ рые можно оценить и на их основе принять собственное решение относительно тре+ бований разработки конкретного приложения.
1.SQLite ++++++ это, как уже отмечалось, ‘‘бессерверная’’ технология. В отличие от многих других баз данных, система SQLite не содержит клиентского и сервер+ ного компонентов. Вместо этого SQLite представляет собой C+библиотеку для обработки данных, которая предназначена для простой интеграции и разра+ ботки приложений. С другой стороны, удаленный доступ к базе данных реали+ зован практически вне всякого сомнения.
2.SQLite не поддерживает типы данных. На Web+сайте SQLite опубликована ин+ тересная дискуссия по этой теме. Она сосредоточена вокруг последовательной защиты автором своей точки зрения по этому вопросу. Цитата: ‘‘Это не дефект, а часть замысла. База данных предназначена для хранения и извлечения данных, и ей должно быть безразлично, в каком формате хранятся эти данные. Строгая типиза* ция, используемая в большинстве других SQL*систем и закодированная в языке SQL, яв* ляется вредным пережитком ****** это пример реализации, которая ‘‘проступает’’ через интерфейс. SQLite пытается преодолеть этот пережиток, позволяя хранить любые типы данных в любых столбцах, обеспечивая гибкость спецификации баз данных.’’
Не нужно быть пуристом в программировании, чтобы оценить влияние стро+ гой типизации на производительность крупных реляционных баз данных. Од+ нако ‘‘отсутствие типов’’ значительно упрощает проектирование и создание таблиц, а в случае SQLite таблицы действительно так малы, как это возможно. Это особенно важно в условиях ограниченности таких ресурсов, как память и дисковое пространство. И поскольку PHP также главным образом использует+ ся слабая типизация, это не представляет реальной угрозы.
3.Неполный SQL: создатель SQLite Хипп подтверждает несколько недостающих частей SQL+стандарта: не реализованы ограничения внешнего ключа, триггеры поддерживаются не полностью, а только одиночные одновременные транзак+ ции, не полностью реализованы многие типы JOIN+операций, в частности пра+ вое и полное внешнее объединение. Самый большой недостаток ++++++ недоступен синтаксис ALTER TABLE, хотя его появление ожидается в ближайшем будущем. В настоящее время для внесения изменений в структуру необходимо сохранить данные во временной таблице, удалить старую таблицу, создать ее заново с но+ вой структурой, а затем импортировать данные из временной таблицы.
776Приложение В
4.Схема привилегий: в списке недостающих элементов SQL также находятся ко+ манды GRANT и REVOKE. Хипп объясняет это тем, что привилегии бессмыслен+ ны во встраиваемой СУБД. Однако с этим можно не согласиться. Привилегии доступа, по существу, контролируются правами доступа к дисковым файлам, а это не легко реализовать в PHP, работающем в безопасном режиме (safe_mode = on). Если разработчику понадобится управлять привилегиями, то, по сути, ему при+ дется разработать встроенную в приложение систему контроля привилегий.
Ниже перечислено еще несколько интересных моментов.
Файлы данных легко распространяются независимо от платформы.
Двоичные данные перед вставкой должны кодироваться в текстовом виде и де+ кодироваться перед отображением. Для этого в PHP поддерживается внутрен+ няя реализация SQLite, а, кроме того, можно использовать другие стандартные PHP+функции.
Поддерживаются базы данных размером до 2 терабайт.
Измерения скорости для небольших баз данных имеют подающие надежды резуль+ таты; общедоступной информации по тестированию крупных баз данных пока нет.
Если, изучив представленную выше информацию, вы решили, что SQLite хорошо подходит для ваших потребностей, можете переходить к чтению следующего раздела.
Использование SQLite в PHP
PHP предоставляет множество функций для работы с базами данных SQLite. Тот, кто уже использовал PHP с другой СУБД, может очень легко догадаться, как работать с SQLite+базами данных. Однако при работе с дисковыми файлами баз данных следует учитывать некоторые особенности этой системы.
Создание и поддержка соединений
В приведенной ниже таблице описаны общие функции для подключения и управ+ ления базами данных.
Функция |
Синтаксис |
Описание |
|
|
|
sqlite_open() resource sqlite_open |
Открывает или создает базу данных SQLite. В качестве |
|
|
(string filename [, |
параметра принимает абсолютный или относительный |
|
int mode [, string |
путь и имя файла базы данных. Параметр mode (режим) |
|
&error_message]]) |
в настоящее время не поддерживается библиотекой |
|
|
SQLite, но его планируется использовать для |
|
|
управления правами доступа к базе данных. |
Во время выполнения сценария для операций, не требующих записи в базу данных (например, SELECT-запрос), могут быть установлены права “только для чтения”.
Сообщение об ошибке (error_message) представляет собой переданную по ссылке переменную, содержащую описательное сообщение об ошибке, переданное SQLite и поясняющее, почему невозможно было открыть базу данных
|
|
|
Использование SQLite 777 |
|
|
|
|
Окончание таблицы |
|
|
|
|
|
|
|
Функция |
Синтаксис |
Описание |
|
|
|
|
|
|
|
sqlite_popen() |
resource sqlite_popen |
Версия функции sqlite_open, создающая |
|
|
|
(string filename [, int |
постоянное соединение. Функция ищет и |
|
|
|
mode [, string |
возвращает существующий дескриптор, а если не |
|
|
|
&error_message]]) |
находит его, то создает новое постоянное соединение |
|
|
sqlite_close() |
void sqlite_close |
Закрывает указанный дескриптор базы данных |
|
|
|
(resource dbhandle) |
|
|
|
sqlite_ |
string sqlite_libencoding |
Возвращает кодировку, которая используется |
|
|
libencoding() |
(void ) |
активной SQLite-библиотекой |
|
|
sqlite_ |
string sqlite_libversion |
Возвращает номер версии активной SQLite-библиотеки |
|
|
libversion() |
(void ) |
|
|
|
sqlite_query() |
resource sqlite_query |
Несмотря на то что имя функции подсказывает, что |
|
|
|
(resource dbhandle, |
ее следует использовать для манипуляции данными |
|
|
|
string query) |
и чтения информации из базы, эта функция |
|
|
|
|
оказывается полезной для создания таблиц данных. |
|
|
|
|
Она возвращает дескриптор результата для |
|
|
|
|
запросов на выборку данных и булево значение |
|
|
|
|
true или false для всех остальных типов запросов. |
|
|
|
|
В отличие от привычных для MySQL-функций, |
|
|
|
|
в данном случае дескриптор результата обязателен. |
|
|
|
|
Работа этой функции при манипуляции данными |
|
|
|
|
описывается в следующей таблице |
|
Манипуляция данными
Вследующей таблице описаны функции, предназначенные для чтения, изменения
исохранения данных.
Функция |
Синтаксис |
Описание |
|
|
|
sqlite_query() |
resource sqlite_query |
Возвращает дескриптор результата |
|
(resource dbhandle, string query) |
с произвольным доступом для запроса |
|
|
query, направленного базе данных, |
|
|
заданной с помощью дескриптора |
|
|
dbhandle |
sqlite_unbuffered_ |
resource sqlite_unbuffered_query |
Аналогичнафункцииsqlite_query() |
query() |
(resource dbhandle, string query) |
за исключением того, что результаты |
|
|
возвращаются в виде последователь- |
|
|
ного результирующего множества |
|
|
с однонаправленным доступом |
sqlite_seek() |
bool sqlite_seek |
Ищет строку, заданную параметром |
|
(resource result, int rownum) |
rownum; если находит, возвращает |
|
|
True, False — в противном случае |
sqlite_next() |
bool sqlite_next |
Передвигает указатель результата |
|
(resource result) |
на следующую строку. Возвращает |
|
|
False, если следующей строки нет |
sqlite_rewind() |
bool sqlite_rewind |
Возвращается обратно к первой |
|
(resource result) |
строке результирующего множества. |
|
|
Если результирующее множество |
|
|
пусто, возвращает False |
780 Приложение В
Практическое использование SQLite
Большинство ключевых PHP+функций для работы с другими базами данных дубли+ рованы для SQLite. Однако вряд ли разработчик захочет внедрять незнакомое средст+ во, не прошедшее документированного крупномасштабного тестирования в реальных условиях, и это правильно. Подходящими приложениями для экспериментирования с SQLite могли бы стать гостевая книга, небольшая система складского учета, система управления пользователями сайта или диспетчер форм.
Далее приведен пример разработки на базе SQLite простого приложения для управления персональной библиотекой.
Приложение “Персональная библиотека”
Рамки книги не позволяют описать создание очень сложного приложения, поэто+ му такие моменты, как наличие нескольких авторов, нескольких изданий и т.д., не принимаются во внимание. С другой стороны, затронутые темы помогут разработчи+ ку обрести уверенность в своих силах. В этом разделе в качестве примеров приведены отдельные фрагменты кода, а весь код окончательного продукта доступен для загруз+ ки с сайта издательства.
Для начала необходимо подготовить каталог для хранения SQLite+баз данных. Лучше всего использовать каталог, находящийся за пределами Web+дерева, но доступ+ ный пользователю, от имени которого работает Web+сервер, чтобы приложение мог+ ло считывать и записывать в него данные. Для целей данного примера в Unix можно использовать каталог /var/sqlite или создать подкаталог sqlite в соответствую+ щем каталоге Windows+системы.
Затем следует определить структуру таблиц. По каждой книге желательно хранить следующую информацию:
название;
автор;
год издания;
издательство;
дата прочтения;
рейтинг.
После чего можно заставить SQLite создать соответствующие таблицы.
Создание базы данных и таблиц
Для создания необходимой структуры базы данных в этом случае используется ко+ роткий сценарий books_table_create.php, который очень похож на сценарий для работы с MySQL+базой данных, созданный в главах 9, 10 и 11:
<html>
<head>
<title>Создание базы данных и таблиц "Персональной библиотеки"</title> </head>
<body>
<?php
echo ( '<p>Создание базы данных и таблиц с помощью SQLite версии: '
. sqlite_libversion() . '</p>' );
Использование SQLite 781
Очевидно, что первую строку PHP+кода в этом сценарии использовать не обязатель+ но, но поскольку в данном случае SQLite запускается на машине впервые, эта строка оп+ ределенно может предоставить полезную информацию. Сбой в этой строке объяснит многие последующие проблемы. Корректное выполнение строки сообщает о том, на+ сколько современной является библиотека; эта информация полезна для отладки.
Далее необходимо определить базу данных, которую будет использовать сценарий, а затем открыть дескриптор с помощью функции sqlite_open(). Следует отметить, что если указанная база данных еще не существует, то эта функция создает ее:
$libraryDB = "/var/sqlite/library";
if ($db = @sqlite_open($libraryDB, 0666, $error)) {
print ( '<p>SQLite-база данных library успешно создана</p>' ); $sql = "CREATE TABLE books (
book_id INTEGER PRIMARY KEY, book_title VARCHAR, book_author VARCHAR, book_pub_year INTEGER, book_publisher VARCHAR, book_read VARCHAR, book_score VARCHAR, book_loan VARCHAR
)";
Предположим, что база данных успешно создана и распечатаны некоторые сооб+ щения о текущем состоянии дел:
if ( @sqlite_query($db, $sql) ) {
print ( '<p>SQLite-таблица books успешно создана</p>' );
} else {
print ( '<p>SQLite-таблица books не создана из-за ошибки:
<br />' . sqlite_error_string(sqlite_last_error($db)) . '</p>' );
}
} else {
print ( '<p>SQLite-база данных library не создана из-за ошибки: <br />' . $error . '</p>' );
}
?>
</body>
</html>
Здесь следует отметить несколько моментов. Во+первых, при перехвате ошиб+ ки результат функции sqlite_last_error() непосредственно передается функции sqlite_error_string(). Подобная краткая запись впоследствии может принести реальную экономию времени.
Во+вторых, несмотря на ‘‘отсутствие’’ типов в SQLite, в определении таблицы включены типы (хотя и очень общие). SQLite принимает (и возвращает) информа+ цию о самых базовых SQL+типах данных, даже несмотря на то, что не использует ее. Впоследствии это позволит другим программистам быстрее понять замыслы создате+ ля программы и может послужить хорошим напоминанием ему самому, когда понадо+ бится перенести приложение на другую СУБД.
Наконец, необходимо отметить важное исключение в аспекте обычной работы SQLite с типами данных. Столбец book_id определен как INTEGER PRIMARY KEY. Это сообщает SQLite, что данное поле предназначено в качестве уникального индекса. Той же цели можно достичь, используя только SQL+слова PRIMARY KEY для нечисло+ вого первичного ключа или UNIQUE для того, чтобы записи в любом не ключевом по+ ле не повторялись. Хотя чистый эффект любой из этих трех комбинаций один и тот