ресурс для начинающих веб-разработчиков
комплексные веб-услуги по созданию сайтов

Справочный материал по основным языкам программирования и верстки сайтов.

Готовая методика создания простых и сложных динамичных сайтов, с использованием PHP и MySQL.

Использование веб-редактора Adobe Dreamweaver в разработке сайтов.

Использование графических редакторов Adobe Flash, Adobe Photoshop, Adobe Fireworks в подготовке веб-графики.

Разработка веб-сайтов под "ключ".

Разработка отдельных фрагментов сайтов, консультации по вопросам верстки веб-страниц и веб-программирования.

Доступ к базе данных MySQL с помощью РНР. Выполнение запросов к базе данных с помощью РНР

Доступ к базе данных MySQL

До сих пор, в примерах для хранения и извлечения данных мы использовали двумерные файлы. Там же, мы говорили о том, что применение систем реляционных баз данных обеспечивает более простое, безопастное и эффективное выполнение задач хранения и извлечения данных. Теперь, поработав с MySQL над созданием базы данных, можно приступать к подключению этой базы данных к внешнему веб-интерфейсу.

Как работают базы данных

  1. Веб-браузер пользователя выдает HTTP-запрос определенной веб-страницы. Например, пользователь ищет в Интернет-магазине все книги, написанные Виктором Смирновым, используя HTML-форму. Страница с результатами поиска будет называться results.php.
  2. Web-сервер принимает запрос на results.php, извлекает этот файл и передает на обработку механизму РНР.
  3. Механизм РНР приступает к разбору сценария. Сценарий содержит команду соединения с базой данных и выполнения запроса (поиска книг). РНР открывает соединение с MySQL-сервером и отправляет соответствующий запрос.
  4. Сервер MySQL принимает запрос к базе данных, обрабатывает его и отправляет результат (список книг) обратно механизму РНР.
  5. Механизм РНР завершает выполнение сценария, что обычно включает в себя форматирование результатов запроса в HTML. После этого результат в виде HTML возвращается Веб-серверу.
  6. Веб-сервер пересылает HTML в браузер, и пользователь имеет возможность просмотреть запрошенный список книг.

У нас имеется база данных MySQL, поэтому можем подготовить код РНР, для выполнения описанных шагов. Начнем с поисковой формы. Это простая HTML-форма. Код для этой формы показан в листинге.

search.php —поисковая страница для БД Интернет-магазин

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<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>
<html>
<head>
<meta charset="utf-8">
<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 % и _(подчеркивание). Эта возможность исключительно полезна для пользователей. Если упомянутые символы создают проблемы в вашем приложении, можете отменить их.

Выполнение запросов к базе данных

В любом сценарии, который обеспечивает доступ к базе данных из Веб, необходимо выполнить ряд базовых шагов:

  1. Проверить и отфильтровать данные, поступающие от пользователя.
  2. Установить соединение с требуемой базой данных.
  3. Реализовать запрос к базе данных.
  4. Получить результаты.
  5. Представить результаты пользователю.

Именно эти действия выполняет сценарий 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);

В явном отсоединении нет особой необходимости, поскольку по завершении выполнения сценария соединение будет закрыто автоматически.