Автор: Пользователь скрыл имя, 16 Марта 2014 в 15:09, курсовая работа
Стоит заметить, что в 1994 году никаких инструментов для создания различных приложений для Web еще не было, да и сам Web только еще начинался. Поэтому те задачи, которые решала программа Расмуса, были актуальны для очень многих пользователей сети, и к нему хлынул поток писем с просьбами предоставить свой инструментарий. К концу 1997 года два программиста Зив Сураски и Энди Гутманс переписали первоначальный лексический анализатор, и к лету 1998 года в полной мере увидела свет третья версия языка - PHP 3. Развитие PHP стремительно продолжалось, в язык сотнями добавлялись новые функции, и в 1999 году число разработчиков, использующих PHP, превысило 1 миллион, что сделало PHP одним из самых популярных языков для разработки Web - приложений. К этому времени к разработке языка подключилось большое количество программистов со всего мира.
resource mysql_query (string query)
Эта функция применяется для отправки серверу SQL-запросов. Функция возвращает дескриптор запроса в случае успеха и false — в случае неудачного выполнения запроса.
В листинге показан код, с помощью которого извлекается одна строка из таблицы customers базы данных books:
<?
include "config.php";//Подключение к серверу и выбор базы данныхх
$ath = mysql_query("select * from customers;");
if($ath)
{
$author = mysql_fetch_array($ath);
echo "<br>имя = ".$author['name']."<br>";
echo "адрес = ".$author['city']."<br>";
}
else
{
echo "<p><b>Error: ".mysql_error () . "</b></p>" ;
exit () ;
}
?>
Результат выполнения запроса для вывода одной строки из таблицы (рисунок 8):
Рисунок 8 – Вывод запроса вывода строки
2. Вывод всех строк таблицы базы данных в виде ассоциативного массива. Функция mysql_fetch_array
array mysql_fetch_array (resource result)
Эта функция возвращает значения полей в виде ассоциативного массива. В качестве аргумента принимает дескриптор запроса, возвращаемый функцией mysql_query.
В листинге показано, как с помощью этой функции можно вывести все строки таблицы customers:базы данных books
<?
include "config.php";//Подключение к серверу и выбор базы данных
$ath = mysql_query("select * from customers;");
if($ath)
{
//Определяем таблицу и
echo "<table border=1>";
echo"<tr>
<td>имя</td>
<td>адрес</td>
</tr>";
//Так как запрос возвращает несколько строк, применяем цикл
while($author = mysql_fetch_array($ath))
{
echo "<tr>
<td>".$author['name']." <
<td>".$author['city']."   </td>
</tr>";
}
echo "</table>";
}
else
{
echo "<p><b>Error: " .mysql_error () . "</b><p>";
exit () ;
}
?>
Результат выполнения запроса для вывода всех строк из таблицы (рисунок 9):
Рисунок 9 – Вывод запроса для вывода всех строк
3. Доступ к отдельному полю записи. Функция mysql_result
mixed mysql_result (resource result, int row)
С помощью этой функции можно получить доступ к отдельному полю записи. Допустим, нам нужно вывести имя автора, которое первым найдется в базе данных. Сделать это можно следующим образом:
<?
include "config.php";//Подключение к серверу и выбор базы данных
$ath = mysql_query("select name from customers;");
if($ath)
{
echo mysql_result($ath,0,'name');
}
else
{
echo "<p><b>Error: " .mysql_error () . "</b><p>";
exit () ;
}
?>
Результат выполнения запроса для вывода одной записи из таблицы (рисунок 10):
Рисунок 10 – Вывод запроса для одной записи
4. Возвращение поля записи в виде объекта. Функция mysql_fetch_object
object mysql_fetch_object (resource result)
Эта функция возвращает поля записи данных в виде объекта.
В листинге приведен пример, в котором с помощью этой функции из таблицы customers выводятся имя, и адрес авторов:
<?
include "config.php";//Подключение к серверу и выбор базы данных
$ath = mysql_query("select * from customers;");
if($ath)
{
while($row = mysql_fetch_object($ath))
{
echo "<p>имя: ".$row->name."</p>";
echo "<p>адрес: ".$row-> city."</p>";
}
}
else
{
echo "<p><b>Error: ".mysql_error () . "</b><p>";
exit();
}
?>
Результат выполнения скрипта (рисунок 11):
Рисунок 11 – Вывод скрипта
5. Возвращение массива, в котором содержится значение поля. Функция mysql_fetch_row
array mysql_fetch_row (resource result)
В отличие от функции mysql_fetch_object, эта функция возвращает не объект, а массив, в котором содержатся значения полей:
<?
include "config.php";//Подключение к серверу и выбор базы данных
$ath = mysql_query("select * from customers;");
if($ath)
{
while($row = mysql_fetch_row($ath))
{
echo "<p>имя: ".$row[3]."</p>";
echo "<p>адрес: ".$row[2]."</p>";
}
}
else
{
echo "<p><b>Error: " .mysql_error () . "</b><p>";
exit ();
}
?>
Запросы, отправляемые серверу MySQL, представляют собой обыкновенные строки РНР:
mysql_query("INSERT INTO table SET name='$name'");
В $name может храниться строка, содержащая апострофы.
Рассмотрим, какой запрос придет серверу MySQL, если $name равно "cat's":
INSERT INTO table SET name='cat's'4.
Эта команда синтаксически некорректна и породит ошибку во время выполнения.
Но может быть и хуже.
Рассмотрим такой запрос:
mysql_query("DELETE FROM table WHERE name='$name'");
Если параметр $name приходит из формы, и злоумышленник указал в нем следующую строку: "!' or 1=1 or '!", то после подстановки получится такой запрос к базе данных:
DELETE FROM table- WHERE name=' !' OR 1=1 OR ' !'
Этот запрос удалит все записи из таблицы table, потому что выражение SQL 1=1 всегда истинно.
Рассмотрим два способы защиты от подобных ошибок или действий злоумышленника:
- Экранирование спецсимволов.
- Шаблоны запросов и placeholders.
Прежде чем передавать значения переменных формы в SQL-запросы, необходимо специальным образом экранировать в них некоторые символы (в частности, апостроф), например, поставить перед ними обратный слэш. Для вставки предназначена функция:
mysql_escape_string()
string mysql_escape_string(string $str)
Функция похожа на другую функцию addslashes(), однако она добавляет слэши перед более полным набором специальных символов. Практика показывает, что для текстовых данных можно применять и функцию addslashes() вместо mysql_escape_string(). Во многих скриптах так и делается.
По стандарту MySQL экранированию подвергаются символы, которые в РНР записываются так: "\х00", "\n", "\г", "\\", ""', "" и "\х1А"5.
В это число входит символ с нулевым ASCII-кодом, а поэтому mysql_escape_string() допустимо применять не только для текстовых, но также и для бинарных данных. Можно, например, считать в переменную GIF-изображение (функция file_get_contents ()), а затем вставить его в базу данных, предварительно проэкранировав все спецсимволы. При извлечении картинка окажется в том же виде, в котором она была изначально.
Экранирование символов это лишь способ записи корректных SQL-выражений, не более того. С данными ничего не происходит, и они хранятся в базе без дополнительных слэшей — так, как выглядели изначально, еще до экранирования.
С использованием mysql_escape_string()код предыдущего запроса выглядит так:
mysql_query(
"DELETE FROM table WHERE name='".mysql_escape_string($
Это длинно, неуклюже и некрасиво.
Рассмотрим другое решение.
Вместо явного экранирования и вставки переменных в запрос на их место помещают специальные маркеры (placeholders, "хранители места"), обычно выглядящие как ?.
Те же значения, которые будут подставлены вместо них, передаются отдельно, дополнительными параметрами.
С использованием гипотетической функции mysql_qwo, код которой будет представлен ниже, предыдущий запрос может быть переписан так:
mysql_qw ('DELETE FROM table WHERE name=?', $name)6;
Запрос стал короче и лучше защищен: теперь мы уже при написании кода не сможем случайно пропустить вызов функции mysql_escape_string() и, таким образом, попасться на уловку хакера. Все преобразования происходят автоматически, внутри функции.
В листинге lib_mysql_qw.php содержится простейшая реализация функции mysql_qw() (qw — от англ. query wrapper, "обертка для запроса").
В большинстве ситуаций возможностей, предоставляемых функцией 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_
// Вызываем 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"
}
?>
Если убрать поясняющие записи, то размер файла 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_
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"
}
?>
Функция sprintf() воспринимает символ % как управляющий. Чтобы отменить его специальное действие, необходимо его удвоить, что и делается в функции. Затем ? заменяется на %s, для sprintf() это означает "взять очередной строковый аргумент"7.
Для удобства тестирования этого кода главная функция разбита на две, выделен код замены подстановочных знаков в функцию mysql_make_qw().
В листинге test_qw.php приведен пример того, как будут выглядеть SQL-запросы после подстановки placeholders.
Информация о работе Разработка web - приложениия “КиноПоиск.Ру” на языке PHP