Лабораторная работа  №5. Работа с базой данных MySQL

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

Структура таблиц будет такой. Таблица описания книг BOOKS:

    id int(5) - уникальный id autoincrement primary key author char(60) - автор namebook text(100) - название книги series int(2) - id серии (если книга принадлежит серии) - для серий отдельная таблица edition int(2) - издание year int(4) - год издания isbn char(20) - ISBN pages int(4) - объем книги when_create int(2) - номер квартала how int(4) - предположительная цена status int(1) - id статуса: обязательно заказать, посмотреть подробнее и т. п.

В качестве направлений развития проекта можно добавить серии книг, статусы, таблицу оглавлений и обложек (в blob-ах), комментарии к книгам и список интернет-магазинов, в которых книга была обнаружена.

Для создания таблицы нам понадобится создать базу данных в MySQL (назовем ее тоже BOOKS) и в ней уже саму таблицу.

Для этого необходимо:

Запустить сервис Denwer на рабочем столе запустить ярлык “Start Denwer”; в адресной строке браузера набрать http://localhost .Откроется страница настроек пакета Denwer; На странице в разделе Утилиты нажать на ссылку Заведение новых БД и пользователей MySQL;


Ввести имя базы данных books, логин books. Ввести и подтвердить пароль.

Нажать на кнопку Создать БД и пользователя. Вернуться в раздел Утилиты и нажать на ссылку phpMyAdmin.

В окне авторизации в поле пользователь ввести books и ниже указать пароль. Выбрать базу данных books.

НЕ нашли? Не то? Что вы ищете?

Перейти на вкладку SQL

Набрать запрос к базе данных на создание таблицы.

create table books (

id int(5) not null primary key auto_increment,

author char(60),

namebook varchar(100),

series int(2),

edition int(2),

year int(4),

isbn char(20),

pages int(4),

when_create int(2),

how int(4),

status int(1)

);

Заполним таблицу содержимым, для этого необходимо выполнить запрос:

insert into books (

id, author, namebook, series, edition, year, isbn,

pages, when_create, how, status)

values (null, "Р. Яргер и др.",

"MySQL и mSQL. Базы данных для небольших предприятий и Интернета",

0, 0, 2000, "5-93286-010-3", 557, 3, 170, 0),

(null, "Ларри УОЛЛ", "Программирование на Perl",

0, 3, 2001, null, 1200, 5, null, 0);

Теперь напишем скрипт для нашей первой страницы.

Комментарии к скрипту

Даже в такой упрощенной форме код работы с mysql избыточен. Т. к. мы работает с одной базой, да еще и делаем единственный запрос, то вместо mysql_connect(), mysql_select_db() и mysql_query() достаточно было вызвать mysql_db_query(). Эта функция при необходимости выполнит коннекцию (в прочем, в этом она не одинока), выберет базу данных и выполнит запрос к базе.

mysql_close() тоже необязательна, т. к. соединение с сервером будет автоматически закрыто при окончании скрипта.

mysql_free_result() - освобождает память после запроса.

Функции implode() и explode() относятся к строковым:

    explode() создает массив из фрагментов строки, разбирая ее как строку с разделителем, указанном в первом параметре. implode() делает обратную операцию.

Эта пара применена для удобства - это проще, чем набирать строку в виде "...текст</th><th>текст..." и уж тем более проще, чем делать кучу echo с текстами, обрамленными тегами <th>/</th>.

В скрипте постоянно используется функция DIE() с параметром "mysql_errno($link).mysql_error($link)". Функция DIE(текст) выводит текст в выходной поток (в HTML-код) и прерывает дальнейшее выполнение скрипта. В данном случае текст для DIE() формируется двумя функциями из группы mysql-функций: MYSQL_ERRNO() - код ошибки и MYSQL_ERROR() - текст ошибки.

Оператор PHP "точка" конкатенирует строки. Необязательный параметр (здесь переменная $link) - идентификатор, возвращаемый функцией MYSQL_CONNECT() после соединения с сервером. Текст же ошибки, возвращаемый функцией MYSQL_ERROR(), выбирается из файлов, расположенных в подкаталоге "share" директории, в которой установлен MySQL.

Секция PHP в файле открыта, как всегда, тегом "<?php". Далее объявляются переменные для работы с функциями MySQL (лучше такие переменные выносить в отдельные файлы и включать в скрипты, скажем, функцией REQUIRE() или INCLUDE()).

Перед началом работы с MySQL выполняем соединение с сервером:

$link=MYSQL_CONNECT($host,$user,$pass);

К $host может быть приписан через двоеточие номер tcp-порта, который слушает сервер в надежде, что кто-нибудь его позовет. По умолчанию порт 3306. Изменяется это значение опять же в my. ini.

Следующая функция - MYSQL_SELECT_DB(). Она имеет два параметра: первый - имя базы, и второй (необязательный) - id соединения ($link). Под необязательностью идентификатора соединения как параметра понимается следующее. Если параметр не указан, то используется последнее открытое соединение. А если ни одно соединение не открыто, то неявно выполняется connect (т. е. при использовании одного соединения MYSQL_CONNECT() явно вызывать не обязательно).

Теперь формируем запрос к базе. Для этой цели используется функция MYSQL_QUERY() или MYSQL_DB_QUERY(). Разница между ними, как Вы, наверное, уже догадываетесь, заключается в том, что первая из них предполагает, что база данных уже выбрана, а вторая наряду с выполнением запроса осуществляет выбор базы.

Параметры: MYSQL_QUERY(строка запроса [, $link]), где $link - идентификатор коннекта, возвращаемого функцией MYSQL_CONNECT(); MYSQL_DB_QUERY(база данных, строка запроса [, $link])). Как обычно, если не указан $link, то используется последнее выполненное соединение. Обе функции выполняют соединение с mysql-сервером (MYSQL_CONNECT()), если ранее не выполнено такое соединение. При этом неявный вызов MYSQL_CONNECT() осуществляется без параметров, используя в качестве имени хоста "localhost", а в качестве имени пользователя и пароля - пустые строки. И обе функции возвращают переменную (идентификатор ресурса), которую потом нужно использовать при обработке запроса (см. ниже). Например,

mysql_select_db("books");
$result = mysql_query("select * from books");

или

$result = mysql_db_query("books","select * from books");

Теперь самое интересное - обработка запроса. Эта операция осуществляется с помощью fetch-группы функций PHP: MYSQL_FETCH_ARRAY(), MYSQL_FETCH_FIELD(), MYSQL_FETCH_LENGTHS(), MYSQL_FETCH_OBJECT() и MYSQL_FETCH_ROW(), а также некоторыми дополнительными функциями (функций управления fetch-курсором, информационными функциями и пр.). Эти функции возвращают очередную строку выборки в виде массива или объекта, перемещая внутренний указатель на следующую строку. Поэтому их следует использовать в циклах.

Сразу небольшое замечание. Среди mysql-функций в PHP есть MYSQL_RESULT(). Она возвращает значение одного столбца в указанной строке. В мануале рекомендуют вместо нее использовать более быстрые функции fetch-группы. Кроме того, по моему мнению, эта функция самая неудобная для работы с выбранными данными. Посему эту функцию я рассматривать не буду.

В скрипте мы использовали функцию MYSQL_FETCH_ROW(). Итак, в результате выполнения одной из двух query-функций мы имеем указатель на ресурс выборки. Пусть сей указатель хранится в переменной $result. Тогда в таком цикле:

while ($data=mysql_fetch_row($result)) {

echo implode(" | ",$data), "<br>";

}

можно вывести результаты запроса. Эта функция возвращает массив (здесь $data), в котором каждый элемент - поле строки выборки, возвращаемое select-ом в query-функции. Функция из string-группы IMPLODE() вернет строку, состоящую из элементов массива, указанного во втором параметре, разделенных разделителем - первым параметром.

Теперь попробуем повторить вывод результатов запроса дважды (пример, конечно, надуманный, но на практике иногда требуется пройтись по результатам запроса более одного раза):

echo "Первый раз";

while ($data=mysql_fetch_row($result)) {

echo implode(" | ",$data), "<br>";

}
echo "Второй раз";

while ($data=mysql_fetch_row($result)) {

echo implode(" | ",$data), "<br>";

}

После строки "Второй раз" мы ничего не увидим. Причина в том, что при каждом вызове fetch-функции внутренний указатель (курсор) автоматически переходит к следующей записи. Как только этот указатель доберется до конца выборки, fetch-функция вернет FALSE, и произойдет выход из цикла. Управлять указателем можно с помощью функции MYSQL_DATA_SEEK(). Параметры: id результата и номер строки, на которую надо установить указатель. Отсчет строк начинается с нуля. В последнем примере перед вторым циклом нужно было бы сказать

mysql_data_seek($result, 0);