МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ INTERNATIONAL BANKING INSTITUTE Практическая работа 2 Тема 2/2: Публикация данных из БД на Webсервере Цель — освоить методы публикации данных, хранимых в БД на Web-сервере. Задания: 1. Освоить технологию подключения к БД, хранящимся на сервере с использованием php-скрипта. 2. Освоить технологию публикации всех данных, хранящихся в одной таблице БД в виде динамических html-страниц. 3. Освоить технологию публикации данных, хранящихся в нескольких таблицах в виде динамической html-страницы 4. Освоить технологию публикации данных из БД по заданным параметрам запроса. 5. Освоить методы задания параметров в диалоговой форме и с использованием данных, хранимых в БД. 6. Освоить принципы создания универсальной функции, которая публикует данные из произвольной таблицы БД, и методы использования этой функции для вывода данных из произвольной таблицы. Общие сведения Последовательность операций при публикации данных включает в себя ряд предварительных действий: 1. Установить связь с сервером БД. 2. Проверить корректность связи, если связь корректная, то продолжить работу — перейти к п.3, в противном случае завершить скрипт, передав некоторое сообщение об ошибке. 3. Выбрать БД, из которой вы хотите опубликовать данные. 4. Если операция выбора БД прошла корректно, перейти к дальнейшей обработке п.5, в противном случае завершить работу скрипта, вернув соответствующее сообщение об ошибке. 5. Подготовить sql-запрос, который соответствует публикуемым данным в виде строки символов. 6. Выполнить сформированный sql-запрос, если не произошло ошибки во время выполнения запроса перейти к формированию публикуемых данных п.7, в противном случае завершить выполнение скрипта и сформировать соответствующее сообщение об ошибке. Ваш скрипт на языке PHP должен начинаться с операции подключения к базе данных. Для того, чтобы подключиться к серверу баз данных, надо выполнить следующую команду: $con= mysql_connect('localhost','root',''); Здесь localhost — имя Web-cервера; 1 МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ INTERNATIONAL BANKING INSTITUTE root — имя пользователя, последний параметр соответствует пустому паролю и представляет две подряд идущие одинарные кавычки. Переменной $con — будет присвоен номер канала подключения, если он более 0 (нуля), то подключение прошло удачно, в противном случае подключение не выполнено. Это может произойти из-за того, что вы ошиблись в имени сервера, в имени пользователя или в пароле. Далее следует оператор выбора базы данных $db=$mysql_select_db('lib'); Здесь lib — имя базы данных. Обратите внимание имя базы данных — это символьная константа и мы ее записываем в одинарных кавычках. Переменной $db — будет присвоено значение ошибки при выполнении данной команды, если значение «истинно» (TRUE), то команда выполнена корректно, и можно продолжать работу. Далее следует формирование оператора sql-запроса: $sql= "select * from books"; Здесь * означает, что мы выводим все столбцы из таблицы books. Теперь надо выполнить это запрос на сервере, это делается командой: $result= mysql_query($sql); Здесь $result — это переменная, которая хранит ссылку на результат выполнения запроса. Почему ссылка, а не сам результат? Потому что результат — это много строк, и неизвестно заранее, сколько их будет. Поэтому мы будем обрабатывать их как некоторый безразмерный ассоциативный массив, а переменная $result содержит ссылку на начало этого массива. После выполнение запроса надо проверить — не было ли ошибки, если ошибки не было, то продолжим обработку. Сообщение об ошибке формируется с использованием функций mysql_error() и mysql_errno(). Mysql_errno() возвращает код ошибки. Если ошибки не было, то код равен 0. Mysql_error() формирует текст сообщения об ошибке. Для того, чтобы быть уверенным, что наш запрос не пуст, т. е. результат содержит некоторое количество строк, отличное от нуля, мы можем воспользоваться функцией mysql_num_rows($result), которая как раз формирует число строк в результирующем ассоциативном массиве. Анализ полученного результирующего с использованием функций: mysql_fetch_row($result) mysql_fetch_array($result) mysql_fetch_object($result) 2 массива может быть выполнен МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ INTERNATIONAL BANKING INSTITUTE Результат запроса — это двумерная таблица. Каждая из приведенных функций позволяет получить значения одной строки этой таблицы. Для того, чтобы перейти на следующую строку таблицы, необходимо выполнить следующее обращение к соответствующей функции. То есть все эти функции работают по принципу курсора (поэтому в названии и используется термин fetch — перейти на следующую строку). Поэтому для расшифровки результата мы должны организовать цикл по всем строкам результирующей таблицы. Этот цикл можно организовать с использованием конструкции For() или While(). Для конструкции For() у нас есть количество строк и мы должны организовать внутренний счетчик, который будет работать в пределах заданного числа. Например: $n= mysql_num_rows($result); For($i=0;$i,$n;$i++) { - вывод строки данных } Обработка строки зависит от применяемой функции. Функция mysql_fetch_row($result) — работает максимально быстро, потому что она при расшифровке строки использует числовые индексы массива строки. $row= mysql_fetch_row($result); Echo $row[0],$row[1],$row[2], $row[3]; Здесь $row — массив, в который помещается текущая строка результата. $row[0] — значение первого столбца в текущей строке результат Если у нас есть таблица books и она содержит следующие строки: Содержимое таблицы Books в БД «Библиотека» ISBN Titl Yearizd Pages 0001 Архитектура компьютеров 2006 230 0002 Вычислительные системы и сети 2007 300 0003 Основы теории баз данных 2007 250 то запрос: $sql= “Select * from books”; $result= mysql_query($sql); // количество строк в результате $n= mysql_num_rows($result); For($i=0;$i<$n;$i++) 3 МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ INTERNATIONAL BANKING INSTITUTE { // переход на текущую строку $row= mysql_fetch_row($result); // вывод значений 4-х столбцов Echo ‘<br>’.$row[0],$row[1],$row[2], $row[3]; } Если вы хотите воспользоваться выглядеть следующим образом: циклом while, тогда обработка может While($row= mysql_fetch_row($result)) { Echo ‘<br>’.$row[0],$row[1],$row[2], $row[3]; } Функция mysql_fetch_array($result) позволяет обращаться по имени столбца при расшифровке строки результата. Массив row[] содержит значения одной строки результата, а для расшифровки этой строки мы и обращаемся с указанием имен столбцов, т. е. $row[«name»] содержит значение столбца с именем name в текущей строке результата. Например, расшифровка того же запроса по таблице books будет выглядеть следующим образом: While($row= mysql_fetch_array($result)) { Echo ‘<br>’.$row[‘ISBN’],$row[‘TITL’],$row[‘YEARIZD’], $row[‘PAGES’]; } Имена полей, используемые данной функцией, регистро-зависимы. При создании БД все имена полей переводятся в верхний регистр, поэтому мы в этом регистре и должны к ним обращаться. И, наконец, последняя функция mysql_fetch_object($result) формирует строку результата как объект. В этом случае к свойствам объекта требуется обращаться с использованием ссылки на свойство: $row->ISBN — значение поля ISBN. Цикл обработки с использованием данной функции выглядит следующим образом: While($row=mysql_fetch_object($result)) { Echo '<br>'.$row->ISBN.'-'.$row->TITL.'-'.$row->YEARIZD.'-'.$row->PAGES; } 4 МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ INTERNATIONAL BANKING INSTITUTE Между отдельными значениями мы вставили дефис, чтобы их разделить. Рекомендуем после выполнения запроса освобождать память, которую он занимал. Запросы могут возвращать несколько сотен строк и неразумно при выполнении нового запроса не освободить ранее использованную память серверу может не хватить ресурсов для обработки и ваш скрипт будет обрабатываться очень медленно. Поэтому после выполнения запроса, если это не последняя команда в скрипте, необходимо выполнить функцию mysql_free_result($result). Последним оператором может быть оператор закрытия соединения с базой данных mysql_close(). Однако он необязателен, так как по завершении работы скрипта связь разорвется автоматически. Все задания выполнять в отдельных файлах. Задание 2. 1. Создать файл common.php с глобальными переменными, содержащими имя сервера, имя пользователя, пароль, имя БД. Создать файл 1_1.php, в котором подключить файл common.php командой INCLUDE (см. лекцию). Вывести сообщение о корректности подключения к серверу и выбору БД. Задание 2.2. Создать файл 1_2_1.php, в нем написать скрипт, который выводит содержимое таблицы, books Вашей БД с использованием функции mysql_fetch_row($result) в виде: Таблица - <имя> . Всего строк Содержимое таблицы books. Задание 2.3. Добавить строки в таблицу и снова запустить скрипт 1_2_1.php и убедиться, что выводятся и новые строки. Задание 2.4. Создать файл 1_2_3.php, в нем написать скрипт, который выводит содержимое таблицы Reader c использованием функции mysql_fetch_array. Проверить корректность работы файла при добавлении новых читателелей. Задание 2.5. Создать файл 1_3_1.php, который выводит список читателей (фамилию и имя) с указанием названий книг, которые за каждым числятся. Вывод сделать в виде равномерно заполненных строк, т. е. разрешить повторение фамилий читателей (рис. 2.1). Для перемещения по результирующему массиву использовать функцию mysql_fetch_object(). 5 МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ INTERNATIONAL BANKING INSTITUTE Рис. 2.1 Результаты работы скрипта 1_3_1.php Задание 2.6. Создать файл 1_3_2.php, который выводит список книг для каждого читателя как представлено на рис. 2.2 Для этого провести упорядочение результатов в sqlзапросе по фамилии с использованием раздела order by Name_reader и вывести сначала фамилию читателя, а под ней список книг, которые за данным читателем числятся (рис.2.2). Рис. 2.2. Вывод книг у читателей Добавить книги читателям в БД и снова запустить скрипт 1_3_2.php, убедиться в том, что новое состояние БД отражается в выводимых данных. Данное задание можно выполнить множеством разных способов. Один из способов анализа состоит в том, что вы заводите дополнительную переменную, в которую помещаете имя предыдущего читателя. Получив новую строку из массива результата, вы сравниваете новое имя с именем предыдущего читателя, если они совпадают, то вы выводите только строку с книгами без фамилии читателя, в противном случае вы выводите полную строку. Вы можете разработать собственный способ, отличный от описанного. Задание 2.7. Создать файл 1_4.php, который выводит список книг (названий книг), которые относятся к конкретной области знаний. Код области знаний передавать как параметр в строке вызова, т. е. Использовать протокол Get для передачи данных на сервер (рис. 2.3). 6 МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ INTERNATIONAL BANKING INSTITUTE Рис. 2.3. Передача параметра скрипту 1_4.php по протоколу GET Изменить данные в БД и повторно проверить 1_4.php при задании разных параметров. работоспособность скрипта Задание 2.8. Создать файл 1_5_1_form.html, в котором формируется форма с одним текстовым полем, где будет вводиться название области знаний. Написать скрипт, который будет запускаться при нажатии на кнопку Submit данной формы и будет выводить список книг по требуемой области знаний (рис. 2.4 и 2.5). Рис. 2.4. Форма для ввода названия области знаний Рис. 2.5. Результат обработки Задание 2.9. Трудно помнить наизусть точное название области знаний. Это относится и к другим данным, которые могут служить параметрами запросов при обращении к БД. В этом случае корректно предоставить пользователю возможность выбрать из имеющихся (хранящихся в БД) значений некоторый параметр. Наиболее подходящим элементом управления для задания одиночного значения из списка 7 МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ INTERNATIONAL BANKING INSTITUTE является комбобокс — выпадающий список. Мы помним из курса «Динамическое Web-программирование», что подобный список формируется как управляющий элемент select. Формат этого элемента следующий: <select name="City"> <option value="one"> Первый</option> <option value="two"> Второй</option> … </select> Однако нам вместо констант необходимо вывести в форме уже имеющиеся в БД значения. Как это сделать? Прежде всего следует заметить, если нам надо что-либо загружать из БД, то это будет файл, которому требуется обработка с использованием транслятора php, следовательно, и расширение этого файла будет уже не html, а php. Далее разработаем сценарий формирования элементов выпадающего списка. Подготовить sql-запрос на вывод всех значений названий областей знаний, содержащихся в таблице catalog. Select * from catalog Послать запрос на исполнение серверу. Сформировать теги заголовка формы и начального тега контейнера элемента Select (или перейдя в формат html, или операторами вывода echo или print php). Организовать цикл по расшифровке элементов результирующей таблицы запроса. Сформировать элемент option для текущего элемента, например следующим образом: $v=$row[‘KOD_NOW’]; $s=$row[‘TITLE_NOW’]; Echo “<option value=$v> $s</option>”; Конец цикла. Освободить память, занимаемую запросом. Вывести завершающий тег элемента Select. Вывести элемент submit формы и закрывающий тег всей формы. У вас должна получиться форма вроде указанной на рис. 2.6. 8 МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ INTERNATIONAL BANKING INSTITUTE Рис. 2.6. Форма, формирующая список из таблицы БД Создать файл 1_5_2_form.php, реализующий приведенный выше алгоритм вывода областей знаний из БД. Создать файл 1_5_2.php для обработки данной формы. Этот скрипт вы можете легко получить, скопировав скрипт 1_4.php, и заменив там протокол GET на протокол POST при приеме переменной kod на сервере. Проверьте работоспособность созданных скриптов. У вас в данном задании должно быть 2 взаимодействующих скрипта: один формирует выпадающий список, а второй обрабатывает запрос. Задание 2.10 Разработать универсальную функцию, которая бы позволяла выводить данные из любой таблицы БД в виде таблицы. Действительно, универсальный запрос, который выводит содержимое таблицы SELECT * FROM $table_name Перемещаться по строкам мы умеем, нам теперь необходимо научиться перемещаться по столбцам и выводить названия столбцов. Для этого воспользуемся дополнительными функциями: mysql_list_fields($database,$table_name) — эта функция получить список полей таблицы $table_name в БД $database. позволяет mysql_num_fields($list_f) — функция, которая позволяет сосчитать число полей в таблице. function print_table($table_name) { include (‘common.php’); / * сначала делаем то же, что и раньше: устанавливаем соединение, выбираем базу и получаем список и число полей в таблице, заданной переменной */ 9 МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ INTERNATIONAL BANKING INSTITUTE $db=@mysql_connect($server,$user,$password) or die ('Ошибка подключения : ' . msql_error($link)); $select_db= @mysql_select_db($dbname) OR die('Ошибка в БД '.$dbname.' '.mysql_error()); $list_f = mysql_list_fields($dbname,$table_name); $n1 = mysql_num_fields($list_f); // сохраним имена полей в массиве $names for($j=0;$j<$n1; $j++){ $names[] = mysql_field_name ($list_f,$j); } $sql = "SELECT * FROM $table_name"; // создаем SQL запрос $q = mysql_query($sql,$conn) or die(); // отправляем // запрос на сервер $n = mysql_num_rows($q); // получаем число строк результата //рисуем HTML-таблицу (красивую) echo "&nbsp;<TABLE BORDER=0 CELLSPACING=0 width=90% align=center><tr><TD BGCOLOR='#005533' align=center> <font color='#FFFFFF'><b>$table_name</b></font></td> </tr></TABLE>"; echo "<table cellspacing=0 cellpadding=1 border=1 width=90% align=center>"; // отображаем названия полей echo "<tr>"; foreach ($names as $val){ echo "<th ALIGN=CENTER BGCOLOR='#C2E3B6'> <font size=2>$val</font></th>"; } for($i=0;$i<$n; $i++){ //получаем значение поля в виде ассоциативного массива while($row = mysql_fetch_array($q)) { echo "<tr>"; foreach ($names as $k => $val){ echo "<td><font size=2>&nbsp;$row[$val]</font></td>"; 10 МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ INTERNATIONAL BANKING INSTITUTE // выводим значение поля } echo "</tr>"; } } echo "</table>"; } ?> Разберите скрипт, скопируйте его себе во вновь созданный файл tab_print.inc и отладьте, для этого создайте новый скрипт 1_6.php, в нем командой INCLUDE пригрузите файл tab_print.inc и далее сделайте вызов разработанной функции с заданным именем таблицы БД. Функция выводит таблицу в виде, показанномна рис. 2.7. Рис. 2.7. Пример работы функции print_table Модифицируйте скрипт так, чтобы имя таблицы передавалось как параметр, например по протоколу GET, проверьте работоспособность данного скрипта на всех таблицах. Закончите работу и предъявите все выполненные задания преподавателю, получите зачет по второму практическому занятию. 11