До сих пор, в примерах для хранения и извлечения данных мы использовали двумерные файлы. Там же, мы говорили о том, что применение систем реляционных баз данных обеспечивает более простое, безопастное и эффективное выполнение задач хранения и извлечения данных. Теперь, поработав с MySQL над созданием базы данных, можно приступать к подключению этой базы данных к внешнему веб-интерфейсу.
У нас имеется база данных MySQL, поэтому можем подготовить код РНР, для выполнения описанных шагов. Начнем с поисковой формы. Это простая HTML-форма. Код для этой формы показан в листинге.
search.php —поисковая страница для БД Интернет-магазин
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
<title>Интернет-магазин - Поиск в каталоге</title>
</head>
<body>
<h1>Интернет-магазин - Поиск в каталоге</h1>
<form action="results.php" method="post">
Выберите тип поиска:<br />
<select name="searchtype">
<option value="author">По автору</option>
<option value="title ">По названию</option>
<option value="isbn">По ISBN </option>
</select>
<br />
Введите информацию для поиска:<br />
<input name="searchterm" type="text" size="30" />
<br />
<input name="" type="submit" value="Найти" />
</form>
</body>
</html>
В окне веб-браузера это будет выглядеть ТАК.
После щелчка на кнопке Найти вызывается сценарий results.php. Его полный код показан ниже.
results.php —извлекает результаты запроса из базы данных MySQL и форматирует их для отображения.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
<title>Интернет-магазин - Результаты поиска</title>
</head>
<body>
<h1>Интернет-магазин - Результаты поиска</h1>
<?php
//создание коротких имен переменных
$searchtype = $_POST['searchtype'];
$searchterm = $_POST['searchterm'];
$searchterm = trim ($searchterm);
if (!$searchtype || !$searchterm)
{
echo 'Вы не ввели параметры поиска. Пожалуйста, вернитесь на предыдущую страницу и повторите ввод';
exit;
}
if (!get_magic_quotes_gpc())
{
$searchtype = addslashes ($searchtype);
$searchterm = addslashes ($searchterm);
}
@ $db = new mysqli ('localhost', 'root', 'shop', 'books');
if (mysqli_connect_errno())
{
echo 'Ошибка: Не удалось установить соединение с базой данных. Пожалуйста повторите попытку позже.';
exit;
}
$query = "select * from books
where ".$searchtype."
like '%".$searchterm."%'";
$result = $db -> query($query);
$num_results = $result -> num_rows;
echo '<p>Найдено книг: '.$num_results.'</p>';
for ($i = 0; $i < $num_results; $i++)
{
$row = $result ->fetch_assoc();
echo '<p><strong>'.($i+1).'. Название: ';
echo htmlspecialchars (stripslashes ($row ['title']));
echo '</strong><br> Автор: ';
echo stripslashes ($row ['author']);
echo '<br>ISBN: ';
echo stripslashes ($row['isbn']);
echo '<br>Цена: ';
echo stripslashes ($row['price']);
echo '</p>';
}
$result->free();
$db -> close();
?>
</body>
</html>
Откройте поисковую страницу, заполните форму поиска и нажмите "Найти".
Результаты поиска по автору будут выглядеть следующим образом.
Обратите внимание, что сценарий позволяет вводить групповые символы MySQL % и _(подчеркивание). Эта возможность исключительно полезна для пользователей. Если упомянутые символы создают проблемы в вашем приложении, можете отменить их.
В любом сценарии, который обеспечивает доступ к базе данных из Веб, необходимо выполнить ряд базовых шагов:
Именно эти действия выполняет сценарий results.php, и мы по очереди исследуем каждое из них.
Прежде всего, необходимо удалить все лишние пробелы, которые пользователь мог случайно ввести перед или после критерия поиска. Это делается с помощью функции trim(), применяемой к $searchterm.
$searchterm = trim ($searchterm);
Следующий этап связан с проверкой того, что пользователь указал критерий и тип поиска. Обратите внимание, что она выполняется лишь после удаления лишних пробелов по краям критерия поиска. Если поменять эти действия местами, может возникнуть ситуация, когда критерий не был пустым и поэтому не привел к выводу сообщения об ошибке, но при этом содержал только пробелы, которые полностью удаляются функцией trim():
if (!$searchtype || !$searchterm)
{
echo 'Вы не ввели параметры поиска. Пожалуйста, вернитесь на предыдущую страницу и повторите ввод';
exit;
}
Была выполнена проверка переменной $searchtype несмотря на то, что в данном случае она поступает из HTML-дескриптора SELECT. Может возникнуть вопрос, зачем нужно проверять входные данные. Не забывайте, что с базой данных можен быть связан далеко не один интерфейс.
И еще, если предполагается ввод пользователем каких-то данных, важно исключить из них любые управляющие символы. Как вы наверняка помните мы уже говорили о функциях addslashes(), stripslashes() и get_magic_quotes_gpc(). Мы должны отметить управляющие символы (литерализовать их) в данных, введенных пользователем, перд сохранением их в базе.
В нашем случае осуществляется проверка значения, возвращаемого функцией get_magic_quotes_gpc(). Это значение указывает, выполняется ли автоматическое взятие в кавычки. Если это не так, с помощью функции addslashes() отменяются управляющие символы:
if (!get_magic_quotes_gpc())
{
$searchtype = addslashes ($searchtype);
$searchterm = addslashes ($searchterm);
}
Функция htmlspecialchars() используется для кодировки символов, которые имеют специальное значение в HTML. Наши тестовые данные не содержат символа амперсанда (&), знаков "меньше" (<), больше (>) или двойных кавычек ("), однако амперсанд может встречаться в названиях многих книг. Использование этой функции поможет избежать ошибок в будущем.
В PHP5 имеется новая библиотека для подключения MySQL, называемая mysqli ("i" означает "improved" —улучшеная). В MySQL4 появился новый быстрый протокол подключения, и mysqli позволяет задействовать все его преимущества. Кроме того, библиотека mysqli позволяет использовать два синтаксиса: объектно-ориентированный и процедурный.
Для соединения с сервером MySQL служит следующая строчка сценария:
@ $db = new mysqli ('localhost', 'root', 'shop', 'books');
В этой строке создается экземпляр класса mysqli и предпринимается попытка соединения с хостом 'localhost' с использованием имени 'root', и пароля 'shop'. Соединение будет использовать базу данных 'books'.
В соответствии с объектно-ориентированным подходом, вы вызываете методы полученного объекта для доступа к базе данных. Если вы предпочитаете процедурный подход, mysqli допускает его, то в этом случае подключение будет выглядеть следующим образом:
@ $db = mysqli_connect ('localhost', 'root', 'shop', 'books');
Приведенная функция возвращает ресурс, а не объект. Этот ресурс представляет собой соединение с базой данных, и при использовании процедурного подхода вы должны передать его во все остальные функции mysqli. Данный подход очень похож на работу с файловыми функциями наподобие fopen().
Большинство функций mysqli имеют объектно-ориентированный, и процедурный интерфейс. В общем случае, отличия между ними заключаются в том, сто имена процедурных вариантов функций начинаются с префикса mysqli_, и им необходимо передавать ресурс, который получен в результате вызова функции mysqli_connect(). Исключением из этих правил является подключение к базе данных, так как оно выполняется конструктором класса mysqli.
Результат попытки подключения должен быть проверен, поскольку остальной код в случае неудачного подключения работать не будет. Проверка осуществляется с помощью следующего кода:
if (mysqli_connect_errno())
{
echo 'Ошибка: Не удалось установить соединение с базой данных. Пожалуйста повторите попытку позже.';
exit;
}
Функция mysqli_connect_errno() возвращает номер ошибки либо 0 в случае удачного подключения.
Обратите внимание, что строка, в которой выполняется попытка подключения к базе данных, начинается с операции подавления ошибок @ . В этом случае можно организовать элегантную обработку ошибочных ситуаций. Обработку ошибок можно также реализовать с помощью исключений, однако в данном простом примере их решено не использовать.
Следует помнить, что в MySQL количество соединений, которые могут существовать одновременно, ограничено. Этот предел определяется параметром max_connections. Его назначение, как и родственного ему параметра MaxClients из веб-сервера Apache, вынудить сервер отклонять новые запросы на соединение, чтобы не допустить полного использования ресурсов компьютера в часы наивысшей загрузки или при аварии программого обеспечения.
Значения этих параметров можно изменять, редактируя конфигурационные файлы. Чтобы настроить параметр MaxClients в Apache, следует внести изменения в файл httpd.conf. Настройка параметра max_connections в MySQL осуществляется путем редактирования файла my.conf.
Работая с MySQL из командной строки, необходимо указывать используемую базу данных:
use books;
То же самое необходимо и при подключении из Веб. База данных, которая должна использоваться, указывается в параметре конструктора mysqli или функции mysqli_connect(). Если впоследствии понадобится изменить используемую базу данных, для этого служит функция mysqli_select_db(), доступ к которой осуществляется следующим образом:
$db -> select_db (dbname)
или
mysqli_select_db (db_resource, db_name)
И здесь поддерживаются обе версии функции — объектно-ориентированная и процедурная, причем процедурная отличается льшь префиксом mysqli_ в имени и параметром, в котором должен передаваться ресурс подключения.
Чтобы осуществить запрос, необходимо воспользоваться функцией mysqli_query(). Однако прежде этот запрос необходимо построить:
$query = "select * from books
where ".$searchtype."
like '%".$searchterm."%'";
В этом случае будет выполняться поиск значения, введенного пользователем ($searchtype) в указанном им поле ($searchterm). Вы, вероятно, обратили внимание на то, что для установки соответствия мы употребили like, а не eqal —при поиске в базе данных обычно имеет смысл несколько расширить границы поиска.
Теперь можно выполнить запрос:
$result = $db -> query($query);
Либо, если вы предпочитаете процедурный интерфейс, запрос будет выглядеть так:
$result = mysqli_query ($db, $query);
Вы передаете запрос, который необходимо выполнить, и в случае процедурного интерфейса, связь с базой данных.
Объектно-ориентированная версия возвращает объект результата, а процедурная версия — ресурс результата. В любом случае возвращаемое значение сохраняется в переменной $result для дальнейшего использования. Функция возвращает значение false в случае ошибки.
Существует множество функций, которые позволяют различными способами вычленять нужные фрагменты из объекта или идентификатора результата. Объект или идентификатор результата — это ключ доступа к возвращенным запросом строкам.
В нашем примере мы подсчитали количество возвращаемых запросом строк и воспользовались функцией mysqli_fetch_assoc().
В случае объектно-ориентированного подхода количество возвращенных строк хранится в элементе num_rows объекта результата. Обратиться к упомянутому элементу можно следующим образом:
$num_results = $result -> num_rows;
При процедурном подходе для получения количества возвращенных строк используется функция mysqli_num_rows(), которой необходимо передать идентификатор результата:
$num_results = mysqli_num_rows($result);
Эта информация весьма полезна, если планируется обрабатывать или отображать результаты. Знание количества строк позволяет организовать цикл по ним:
for ($i = 0; $i < $num_results; $i++)
{
//Обработка результатов
}
В каждой итерации этого цикла происходит вызов $result -> fetch_assoc () (или mysqli_fetch_assoc()) Цикл не будет выполняться при отсутствии возвращенных строк. Именно эта функция извлекает каждую строку из результирующего набора и возвращает ее в виде массива, в котором каждый ключ является именем атрибута, а каждое значение соответствующим значением:
$row = $result ->fetch_assoc();
Либо с использованием процедурного подхода:
$row = mysqli_fetch_assoc ($result);
Имея массив $row, можно пройти по всем полям и должным образом отобразить каждое из них:
echo '<br>ISBN: ';
echo stripslashes ($row['isbn']);
Как упоминалось ранее, stripslashes() вызывается для того, чтобы "подчистить" значение, прежде чем отображать его пользователю.
Существует несколько вариантов получения результата из идентификатора результата. Вместо массива с именованными ключами можно воспользоваться нумерованным массивом, применив mysqli_fetch_row():
$row = $result -> fetch_row();
или, в случае процедурного подхода:
$row = mysqli_fetch_row ($result);
Значение атрибутов бутут храниться в каждом из значений $row[0], $row[1] и так далее. Функция mysqli_fetch_array() позволяет получить строку в виде массива обеих типов.
С помощью функции mysqli_fetch_object() можно тоже выбрать строку для помещения внутрь объекта:
$row = $result -> fetch_object();
или так:
$row = mysqli_fetch_object ($result);
После этого доступ к каждому атрибуту можно получить с помощью
$row -> title, $row -> author и так далее
Освобождение результирующего набора выполняются следующим образом:
$result -> free();
или
mysqli_free_result ($result);
Затем можно закрыть соединение с базой данных:
$db -> close();
или
mysqli_close ($db);
В явном отсоединении нет особой необходимости, поскольку по завершении выполнения сценария соединение будет закрыто автоматически.
Похожие материалы по теме:
РНР и MySQL. Соединение с сервером MySQL. Соединение с базой данных