РАБОТА С БАЗОЙ ДАННЫХ MySQL СРЕДСТВАМИ РНР
Лекция. Подготовлена Прохоровым В.С.
1. СОЕДИНЕНИЕ РНР-СЦЕНАРИЕВ с таблицами MySQL
Рассмотрим наиболее часто используемых функций, позволяющих работать с базой данных MySQL средствами РНР.
При взаимодействии РНР и MySQL программа взаимодействует с СУБД посредством совокупности функций.
1.1 Соединение с сервером. Функция mysql_connect
Прежде чем работать с базой данных, необходимо установить с ней сетевое соединение, а также провести авторизацию пользователя. Для этого служит функция mysql_connect()
resource mysql_connect([string $server[,string $username[,string $password]]])
Эта функция устанавливает сетевое соединение с базой данных MySQL, расположенной на хосте $server (по умолчанию это localhost, т.е. текущий компьютер) и возвращает идентификатор открытого соединения. Вся дальнейшая работа ведется именно с этим идентификатором. Все другие функции, принимающие этот идентификатор (дескриптор) в качестве аргумента, будут однозначно определять выбранную базу данных. При регистрации указывается имя пользователя $username и пароль $password (по умолчанию имя пользователя, от которого запущен текущий процесс – при отладке скриптов: root, и пустой пароль):
<?
$dblocation = "localhost"; //Имя сервера
$dbuser = "root"; //Имя пользователя
$dbpasswd = ""; //Пароль
//Осуществляем соединение с сервером базы данных
//Подавляем вывод ошибок символом @ перед вызовом функции
$dbcnx = @ mysql_connect($dblocation, $dbuser, $dbpasswd);
if (!$dbcnx) //Если дескриптор равен 0, соединение не установлено
{
//Выводим предупреждение
echo("<P>B настоящий момент сервер базы данных не доступен, поэтому корректное отображение страницы невозможно.</Р>");
exit ();
}
?>
Переменные $dblocation, $dbuser и $dbpasswd хранят имя сервера, имя пользователя и пароль.
1.2 Разрыв соединения с сервером. Функция mysql_close
Соединение с MySQL – сервером будет автоматически закрыто по завершении работы сценария, либо же при вызове функции mysql_close
bool mysql_close ([resource $link_identifier])
Эта функция разрывает соединение с сервером MySQL, и возвращает true при успешном выполнении операции и false в противном случае. Функция принимает в качестве аргумента дескриптор соединения с базой данных, возвращаемый функцией mysql_connect.
Пример работы с этой функцией:
<?
$dblocation = "localhost"; //Имя сервера
$dbuser = "root"; //Имя пользователя
$dbpasswd = ""; //Пароль
//Осуществляем соединение с сервером базы данных
//Подавляем вывод ошибок символом @ перед вызовом функции
$dbcnx = @ mysql_connect($dblocation, $dbuser, $dbpasswd);
if (!$dbcnx) //Если дескриптор равен 0, соединение не установлено
{
//Выводим предупреждение
echo("<P>B настоящий момент сервер базы данных не доступен, поэтому корректное отображение страницы невозможно.</Р>");
exit ();
}
if (mysql_close($dbcnx)) //разрываем соединение
{
echo("Соединение с базой данных прекращено");
}
else
{
echo("He удалось завершить соединение");
?>
Обработка ошибок
Если в процессе работы с MySQL возникают ошибки (например, в запросе не сбалансированы скобки или же не хватает параметров), то сообщение об ошибке и ее номер можно получить с помощью описанных далее двух функций.
Важно аккуратно и своевременно использовать эти функции, потому что иначе отладка сценариев может усложниться.
● Функция:
int mysql_errno ([int $link_identifier])
возвращает номер последней зарегистрированной ошибки. Идентификатор соединения $link_identifier можно не указывать, если за время работы сценария было установлено только одно соединение.
● Функция:
string mysql_error([int $link_identifier])
возвращает не номер, а строку, содержащую текст сообщения об ошибке. Ее удобно применять в отладочных целях. Обычно mysql_error используют вместе с конструкцией or die (), например:
@mysql_connect("localhost", "user", "password")
or die("Ошибка при подключении к базе данных: ".mysql_error());
Оператор @, как обычно, служит для подавления стандартного предупреждения, которое может возникнуть в случае ошибки.
В последних версиях РНР предупреждения в MySQL-функциях по умолчанию не регистрируются.
Экранирование спецсимволов
Прежде чем передавать значения переменных формы в SQL-запросы, необходимо специальным образом экранировать в них некоторые символы (в частности, апостроф), например, поставить перед ними обратный слэш. Для вставки предназначена функция:
mysql_escape_string()
string mysql_escape_string(string $str)
Функция похожа на другую функцию addslashes(), однако она добавляет слэши перед более полным набором специальных символов. Практика показывает, что для текстовых данных можно применять и функцию addslashes() вместо mysql_escape_string(). Во многих скриптах так и делается.
По стандарту MySQL экранированию подвергаются символы, которые в РНР записываются так: "\х00", "\n", "\г", "\\", ""', "" и "\х1А".
В это число входит символ с нулевым ASCII-кодом, а поэтому mysql_escape_string() допустимо применять не только для текстовых, но также и для бинарных данных. Можно, например, считать в переменную GIF-изображение (функция file_get_contents ()), а затем вставить его в базу данных, предварительно проэкранировав все спецсимволы. При извлечении картинка окажется в том же виде, в котором она была изначально.
Экранирование символов это лишь способ записи корректных SQL-выражений, не более того. С данными ничего не происходит, и они хранятся в базе без дополнительных слэшей — так, как выглядели изначально, еще до экранирования.
С использованием mysql_escape_string()код предыдущего запроса выглядит так:
mysql_query(
"DELETE FROM table WHERE name='".mysql_escape_string($name)."'" );
Это длинно, неуклюже и некрасиво.
Пример применения СУБД MySQL
Рассмотрим некоторые приемы, которые удобно применять в сценариях, требующих обращений к базе данных на примере гостевой книги. С книгой можно проделывать следующие два действия:
● добавлять новую запись; при этом она помечается текущей датой и помещается в таблицу базы данных;
● удалять некоторую запись по ее идентификатору.
Скрипт упрощен: удалять записи позволяется любому пользователю, а не только администратору сайта. При необходимости ограничить права легко: достаточно вставить в скрипт соответствующие проверки.
Листинг guestbook.php
<? php ## Простейшая гостевая книга.
require_once "mysql_connect.php";
require_once "lib_mysql_qw.php";
// Имя таблицы.
define("TBLNAME", "guestbook");
// Создаем таблицу, если она еще не существует.
mysql_qw ('CREATE TABLE IF NOT EXISTS '.TBLNAME.' (
id INT AUTO_INCREMENT PRIMARY KEY,
stamp TIMESTAMP,
name VARCHAR(60),
text TEXT
)
')
or die(mysql_error()) ;
// Обрабатываем кнопки и действия.
if (@$_REQUEST['doAdd'])
{
// Получаем данные из формы.
$element = $_REQUEST['element'];
// Удаляем слэши в данных, которые РНР вставил в режиме
// magic_quotes_gpc (если он включен).
if (ini_get("magic_quotes_gpc"))
$element = array_map('stripslashes', $element);
// Вставляем запись.
mysql_qw(
'INSERT INTO '.TBLNAME. 'SET name=?, text"?',
$element['name'], $element['text']
)
or die(mysql_error());
// Выполняем "самопереадресацию", чтобы при нажатии кнопки
// "Обновить" в браузере сообщение не добавлялось снова и снова.
Header ("Location: {$_SERVER['SCRIPT_NAME']}?".time());
exit ();
}
// Удаление сообщения с указанным ID.
if ($delid = @$_REQUEST['delete'])
{
mysql_qw ('DELETE FROM '.TBLNAME.' WHERE id=?', $delid)
or die(mysql_error());
}
// Выбираем все записи из таблицы, начиная с самой новой.
$result = mysql_qw('
-- Функция MySQL UNIX_TIMESTAMP() конвертирует, timestamp
-- из формата MySQL в число секунд с начала эпохи Unix.
SELECT *, UNIX_TIMESTAMP(stamp) AS stamp
FROM ' . TBLNAME. '
ORDER BY stamp DESC
')
or die(mysql_error());
for ($book=array();
$row=mysql_fetch_array($result);
$book[]=$row);
?>
<! -- Далее идет шаблон книги. -->
<form action="" method="post">
<table>
<tr
<td>Baшe имя:</td>
<td><input type ="text" name="element [name] "></td>
</tr>
<tr
<td>Teкст сообщения:</td>
<td><textarea name="element[text]" cols="60" rows="5"></textarea></td>
</tr>
<tr>
<td> </td>
<td><input type="submit" name="doAdd" value="Добавить"</td>
</table>
</form>
<hr>
<?
foreach($book as $element)
{
?>
<b>
<? =date ("d.m.Y", $element ['stamp'])?>
<? =htmlspecialchars ($element ['name'])?>
</b>
написал:
<a href="<?=$_SERVER['SCRIPT_NAME']?>?delete=<?=$element['id']
?>
">
[удалить]</a>
<br>
<blockquote>
<?=n12br(htmlspecialchars($element['text']))
?>
</blockquote>
<hr>
<?
}
?>
Этот скрипт использует удобные на практике приемы.
● Вначале включают код mysql_connect.php для подключения к базе данных, а также библиотеку lib_mysql_qw.php для выполнения "защищенных" запросов.
Дальше ИСПОЛЬЗУЕТСЯ ТОЛЬКО ФУНКЦИЯ mysql_qw(), и не применяется вызов функции mysql_query() напрямую.
● Создается константа, хранящая имя таблицы гостевой книги в базе данных. Использование константы вместо явного указания имени позволяет в дальнейшем легко сменить имя таблицы (если это понадобится).
● Создается таблица guestbook, имеющая 4 поля (столбца):
○ Автоинкрементное поле id, как обычно, служит для идентификации записей.
○ Поле stamp типа timestamp хранит время изменения данной записи. Тип timestamp удобен тем, что значение stamp изменяется сервером MySQL автоматически при вставке или модификации записи.
● Благодаря фразе IF NOT EXISTS MySQL создаст таблицу только при первом запуске скрипта, и ничего не будет делать при последующих запусках.
Рекомендуется всегда создавать таблицы прямо в скриптах, которые с ними работают, потому, что это делает сценарии автономными. К сожалению многие скрипты так не поступают. Обычно к ним прилагается SQL-файл с командами создания таблиц, который нужно запустить перед установкой скриптов. Этот способ не рекомендуется.
● Режим magic_quotes_gpc, устанавливаемый в файле php.ini, заставляет РНР вставлять слэши перед данными, пришедшими из формы. Так разработчики РНР попытались обезопасить программистов, использующих СУБД от распространенной ошибки с апострофами.
Так как мы обрабатываем апострофы самостоятельно (функция mysql_qw()), нам нужно вернуть данные в исходный вид, т. е. убрать из них все лишние слэши.
Можно подумать, что идея с magic_quotes_gpc хороша, и задаться вопросом: а зачем же вообще нужна функция mysql_qw(), если есть magic_quotes_gpc? Ответ на этот вопрос: данные, помещаемые в базу, могут прийти не только из формы, но и из других источников (a magic_quotes_gpc обрабатывает лишь данные формы).
● Выдавая заголовок Location, мы обеспечиваем так называемую самопереадресацию. Зачем она нужна? Попробуйте убрать вызов Header() (и идущий следом exit()), затем добавить в гостевую книгу запись и тут же нажать кнопку «Обновить» в браузере. Появится запрос: хотите ли вы послать данные формы повторно или нет. Если вы ответите «Да», в книгу добавится еще одна запись, идентичная первой. Если же ответите «Нет», то будет показано старое состояние гостевой книги, без только что добавленной записи. Самопереадресация обеспечивает корректность работы кнопки «Обновить», а добавляемое в query_string текущее время гарантирует, что браузер не станет кэшировать страницу.
● Интересна SQL-команда
SELECT *, UNIX_TIMESTAMP(stamp) AS stamp
Тип данных TIMESTAMP хранит информацию о времени в следующем представлении: 20051222000307. Первые 4 цифры определяют год, следующие две — месяц, и т. д. В то же время, для функции PHP date()нужен Unix timestamp-формат — число секунд, прошедших с 1 января 1970 года. Чтобы преобразовать первое представление во второе, используется функция UNIX_TIMESTAMP(), встроенная в MySQL. Суффикс " AS stamp " позволяет добавить вычисленное поле под именем stamp к остальным полям, которые были извлечены звездочкой (*).
В итоговый набор данных поле stamp должно бы было добавиться в конец списка полей, и результат должен бы получиться из 5 колонок (id, stamp, name, text и еще другая stamp, полученная при помощи " AS stamp " — не важно, что она имеет то же имя, что и вторая). Однако использование функции mysql_fetch_assoc() "гасит" первое поле stamp и заменяет его значением последнего.
Таким образом, в итоге переменная $row равна массиву из четырех элементов: (id, stamp, name, text), причем stamp идет в формате Unix timestamp, что и требовалось.
● При выводе данных в браузер их в обязательном порядке обрабатывают функцией htmlspecialchars(), чтобы злоумышленник не смог вставить в сообщение теги и "разрушить" структуру страницы. Обратите внимание, что данные хранятся в БД в исходном виде, а их обработка производится уже в самом конце, непосредственно перед выводом. Такая практика позволяет, например, легко написать скрипт редактирования записей в гостевой книге, или же изменить ее дизайн (например, добавить
РАБОТА С БАЗОЙ ДАННЫХ MySQL СРЕДСТВАМИ РНР
Лекция. Подготовлена Прохоровым В.С.
1. СОЕДИНЕНИЕ РНР-СЦЕНАРИЕВ с таблицами MySQL
Рассмотрим наиболее часто используемых функций, позволяющих работать с базой данных MySQL средствами РНР.
При взаимодействии РНР и MySQL программа взаимодействует с СУБД посредством совокупности функций.
1.1 Соединение с сервером. Функция mysql_connect
Прежде чем работать с базой данных, необходимо установить с ней сетевое соединение, а также провести авторизацию пользователя. Для этого служит функция mysql_connect()
resource mysql_connect([string $server[,string $username[,string $password]]])
Эта функция устанавливает сетевое соединение с базой данных MySQL, расположенной на хосте $server (по умолчанию это localhost, т.е. текущий компьютер) и возвращает идентификатор открытого соединения. Вся дальнейшая работа ведется именно с этим идентификатором. Все другие функции, принимающие этот идентификатор (дескриптор) в качестве аргумента, будут однозначно определять выбранную базу данных. При регистрации указывается имя пользователя $username и пароль $password (по умолчанию имя пользователя, от которого запущен текущий процесс – при отладке скриптов: root, и пустой пароль):
<?
$dblocation = "localhost"; //Имя сервера
$dbuser = "root"; //Имя пользователя
$dbpasswd = ""; //Пароль
//Осуществляем соединение с сервером базы данных
//Подавляем вывод ошибок символом @ перед вызовом функции
$dbcnx = @ mysql_connect($dblocation, $dbuser, $dbpasswd);
if (!$dbcnx) //Если дескриптор равен 0, соединение не установлено
{
//Выводим предупреждение
echo("<P>B настоящий момент сервер базы данных не доступен, поэтому корректное отображение страницы невозможно.</Р>");
exit ();
}
?>
Переменные $dblocation, $dbuser и $dbpasswd хранят имя сервера, имя пользователя и пароль.
1.2 Разрыв соединения с сервером. Функция mysql_close
Соединение с MySQL – сервером будет автоматически закрыто по завершении работы сценария, либо же при вызове функции mysql_close
bool mysql_close ([resource $link_identifier])
Эта функция разрывает соединение с сервером MySQL, и возвращает true при успешном выполнении операции и false в противном случае. Функция принимает в качестве аргумента дескриптор соединения с базой данных, возвращаемый функцией mysql_connect.
Пример работы с этой функцией:
<?
$dblocation = "localhost"; //Имя сервера
$dbuser = "root"; //Имя пользователя
$dbpasswd = ""; //Пароль
//Осуществляем соединение с сервером базы данных
//Подавляем вывод ошибок символом @ перед вызовом функции
$dbcnx = @ mysql_connect($dblocation, $dbuser, $dbpasswd);
if (!$dbcnx) //Если дескриптор равен 0, соединение не установлено
{
//Выводим предупреждение
echo("<P>B настоящий момент сервер базы данных не доступен, поэтому корректное отображение страницы невозможно.</Р>");
exit ();
}
if (mysql_close($dbcnx)) //разрываем соединение
{
echo("Соединение с базой данных прекращено");
}
else
{
echo("He удалось завершить соединение");
?>
Дата: 2019-07-30, просмотров: 235.