на тему рефераты Информационно-образоательный портал
Рефераты, курсовые, дипломы, научные работы,
на тему рефераты
на тему рефераты
МЕНЮ|
на тему рефераты
поиск
Работа с базой данных MySQL средствами PHP
p align="left">Имеется также библиотека lib/Placeholder.php, обеспечивающая значительно более мощную поддержку языка placeholders: http://dklab.ru/chicken/30.html.

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

Листинг lib_mysql_qw.php

<?php ## Простейшая функция для работы с placeholders.

// result-set, mysql_qw ($connection_id, $query, $argl, $arg2 ...).

// - или -

// result-set mysql_qw($query, $argl, $arg2, ...)

// Функция выполняет запрос к MySQL через соединение, заданное как

// $connection_id (если не указано, то через последнее открытое).

// Параметр $query может содержать подстановочные знаки ?,

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

// аргументов $arg1, $arg2 и т. д. (по порядку), экранированные и

// заключенные в апострофы.

function mysql_qw()

{

// Получаем все аргументы функции.

$args = func_get_args();

// Если первый параметр имеет тип "ресурс", то это ID-соединения.

$соnn = null;

if (is_resource($args[0])) $conn = array_shift($args);

// Формируем запрос по шаблону.

$query = call_user_func_array("mysql_make_qw", $args);

// Вызываем SQL-функцию.

return $conn!==null ? mysql_query($query, $conn): mysql_query($query);

}

// string mysql_make_qw($query, $argl, $arg2,...)

// Данная функция формирует SQL-запрос по шаблону $query,

// содержащему placeholders.

function mysql_make_qw()

{

$args = func_get_args();

// Получаем в $tmp1 ССЫЛКУ на шаблон запроса.

$tmp1 =& $args[0];

$tmp1 - str_replace("%", "%%", $tmp1);

$tmp1 = str_replace("?", "%s", $tmp1);

// После этого $args[0] также окажется измененным.

// Теперь экранируем все аргументы, кроме первого.

foreach ($args as $i=>$v)

{

if (!$i) continue; // это шаблон

if (is_int($v)) continue; // целые числа не нужно экранировать

$args[$i] = "'".mysql_escape_string($v)."'";

}

//На всякий случай заполняем 20 последних аргументов недопустимыми

// значениями, чтобы в случае, если число "?" превышает количество

// параметров, выдавалась ошибка SQL-запроса (поможет при отладке).

for ($i=$c=count($args)-1; $i<$c+20; $i++)

$args[$i+1] = "UNKNOWN_PLACEHOLDER_$i";

// Формируем SQL-запрос.

return call_user_func_array("sprintf", $args);

}

?>

Если убрать поясняющие записи, то размер файла lib_mysql_qw.php уменьшится почти в три раза:

<?php ## Простейшая функция для работы с placeholders.

function mysql_qw()

{

$args = func_get_args();

$соnn = null;

if (is_resource($args[0])) $conn = array_shift($args);

$query = call_user_func_array("mysql_make_qw", $args);

return $conn!==null ? mysql_query($query, $conn): mysql_query($query);

}

function mysql_make_qw()

{

$args = func_get_args();

$tmp1 =& $args[0];

$tmp1 - str_replace("%", "%%", $tmp1);

$tmp1 = str_replace("?", "%s", $tmp1);

foreach ($args as $i=>$v)

{

if (!$i) continue;

if (is_int($v)) continue;

$args[$i] = "'".mysql_escape_string($v)."'";

}

for ($i=$c=count($args)-1; $i<$c+20; $i++)

$args[$i+1] = "UNKNOWN_PLACEHOLDER_$i";

return call_user_func_array("sprintf", $args);

}

?>

Функция sprintf() воспринимает символ % как управляющий. Чтобы отменить его специальное действие, необходимо его удвоить, что и делается в функции. Затем ? заменяется на %s, для sprintf() это означает "взять очередной строковый аргумент".

Для удобства тестирования этого кода главная функция разбита на две, выделен код замены подстановочных знаков в функцию mysql_make_qw().

В листинге test_qw.php приведен пример того, как будут выглядеть SQL-запросы после подстановки placeholders.

Листинг test_qw.php

<?php

require_once "lib_mysql_qw.php";

require_once "mysql_connect.php";

// Представим, что мы - хакеры...

$name = "' OR '1";

// Допустимый запрос.

echo mysql_make_qw('DELETE FROM people WHERE name=?', $name)."<br>";

// Недопустимый запрос.

echo mysql_make_qw('DELETE FROM people WHERE name=? OR ?', $name)."<br>";

// Вот как выглядит выполнение запроса.

mysql_qw('DELETE FROM people WHERE name=? OR ?', $name)

or die(mysql_error());

?>

В результате работы скрипта будет сгенерирована следующая страница:

DELETE FROM people WHERE name='\' OR \'1'

DELETE FROM people WHERE name=' \ ' OR \ ' 1' OR id=UNKNOWN_PLACEHOLDER_l

Unknown column 'UNKNOWN_PLACEHOLDER_1' in 'where clause1

Перед апострофами в данных появились слэши, a placeholder, которому "не хватило" аргументов функции, оказался замененным на строчку UNKNOWN_PLACEHOLDER_l.

Теперь любая попытка выполнения такого запроса заранее обречена на неудачу (о чем говорит последнее диагностическое сообщение, сгенерированное вызовом die()), что является важным подспорьем при отладке сценариев.

3.3 Пример применения СУБД 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 valign="top">

<td>Baшe имя:</td>

<td><input type ="text" name="element [name] "></td>

</tr>

<tr valign="top">

<td>Teкст сообщения:</td>

<td><textarea name="element[text]" cols="60" rows="5"></textarea></td>

</tr>

<tr>

<td>&nbsp;</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(), чтобы злоумышленник не смог вставить в сообщение теги и "разрушить" структуру страницы. Обратите внимание, что данные хранятся в БД в исходном виде, а их обработка производится уже в самом конце, непосредственно перед выводом. Такая практика позволяет, например, легко написать скрипт редактирования записей в гостевой книге, или же изменить ее дизайн (например, добавить

Страницы: 1, 2, 3



© 2003-2013
Рефераты бесплатно, курсовые, рефераты биология, большая бибилиотека рефератов, дипломы, научные работы, рефераты право, рефераты, рефераты скачать, рефераты литература, курсовые работы, реферат, доклады, рефераты медицина, рефераты на тему, сочинения, реферат бесплатно, рефераты авиация, рефераты психология, рефераты математика, рефераты кулинария, рефераты логистика, рефераты анатомия, рефераты маркетинг, рефераты релиния, рефераты социология, рефераты менеджемент.