Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Курсовая работа

.pdf
Скачиваний:
195
Добавлен:
28.06.2014
Размер:
874.29 Кб
Скачать

МОСКОВСКИЙ ЭНЕРГЕТИЧЕСКИЙ ИНСТИТУТ (ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ)

ИНСТИТУТ АВТОМАТИКИ И ВЫЧИСЛИТЕЛЬНОЙ ТЕХНИКИ КАФЕДРА ПРИКЛАДНОЙ МАТЕМАТИКИ

Курсовая работа

Разработка Web API для организации поиска в базах данных MySQL.

Выполнил студент группы А-13-08

каф. Прикладной Математики Захаров Антон

Преподаватель Сидорова Наталья Петровна

Научный руководитель Чибизова Наталья Владимировна

Москва,2011

Содержание.

I. Постановка задачи

2

Определения ключевых понятий

2

Постановка задачи

2

II. Библиотека для работы с базами данных MySQL

3

Система управления базой данных MySQL

3

Описание библиотеки

4

Установка соединения с базой данных

5

Выполнение SQL запросов

6

Пример использования

9

III. Библиотека для поиска в базах данных MySQL

10

Полнотекстовый поиск в MySQL

10

Описание библиотеки

12

Формирование поисковых запросов

14

Пример использования

18

Список литературы

21

1

Часть I.

Постановка задачи.

Определения ключевых понятий.

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

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

Поисковая система – программно-аппаратный комплекс с вебинтерфейсом, предоставляющий возможность поиска информации в Интернете. Под поисковой системой обычно подразумевается сайт, на котором размещён интерфейс системы.

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

Постановка задачи.

Внаши дни умение быстро найти необходимую информацию ценится особенно высоко. И наиболее ярко это можно видеть на примере одной из крупнейших поисковых систем в мире «Яндекс»: только за сентябрь 2011 года было обработано свыше 3 млрд. поисковых запросов. И это всего лишь 1,7% от мирового количества!

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

Вданной работе я постараюсь разработать Web API для организации полнотекстового поиска в базах данных MySQL. В качестве языка программирования будет использовать PHP, интенсивно применяемый для разработки веб-приложений.

2

Часть II.

Библиотека для работы с базами данных MySQL.

Система управления базами данных MySQL.

MySQL – свободная система управления базами данных (СУБД). MySQL является собственностью компании MySQL AB, осуществляющей разработку

иподдержку приложения. Распространяется под GNU General Public License и под собственной коммерческой лицензией, на выбор. Помимо этого компания MySQL AB разрабатывает функциональность по заказу лицензионных пользователей, именно благодаря такому заказу почти в самых ранних версиях появился механизм репликации.

MySQL характеризуется большой скоростью, устойчивостью и лёгкостью в использовании, является решением для малых и средних приложений. Наряду с Oracle Database это одна из самых быстрых СУБД на сегодняшний день. Распространение СУБД MySQL на основе GPL и высокая скорость обработки запросов привело к тому, что эта база данных стала стандартом в услугах сетевого хостинга. Обычно MySQL используется в качестве сервера, к которому обращаются локальные или удалённые клиенты, однако в дистрибутив входит библиотека внутреннего сервера, позволяющая включать MySQL в автономные программы.

Гибкость СУБД MySQL обеспечивается поддержкой большого типа таблиц: пользователи могут выбрать как сверхбыстрые таблицы типа MyISAM, поддерживающие полнотекстовый поиск, так и более медленные, но чрезвычайно устойчивые таблицы InnoDB, поддерживающие транзакции на уровне отдельных записей. Благодаря открытой архитектуре и GPL лицензированию в СУБД MySQL постоянно появляются новые типы таблиц.

MySQL портирована на большое количество платформ: Windows, BSDi, Linux, Mac OS X, NetBSD и др. Важно отметить, что на официальном сайте СУБД для свободной загрузки предоставляются не только исходные коды, но

иоткомпилированные и оптимизированные под конкретные операционные системы готовые исполняемые модули СУБД MySQL.

Исторически СУБД MySQL разрабатывалась для web-сайтов и обеспечивала быструю индексацию данных в хранилищах и оптимизацию последовательного доступа к данным (система хранения ISAM).

Преимущества СУБД MySQL.

Основные преимущества:

высокая производительность

масштабируемость

надёжность

простота использования, простота внедрения

3

открытая и модульная разработка

низкие совокупные затраты (платить нужно только при потребности в поддержке)

MySQL включает API для большого количества языков программирования (Delphi, C, C++, Эйфель, Java, Лисп, Perl, PHP, Python, Ruby, Smalltalk, Tcl, библиотеки для языков платформы .NET)

поддержка MySQL присутствует на большинстве хостингов в Рунете

кроссплатформенность (UNIX системы и среда Microsoft Windows)

гибкая политика лицензирования

Описание библиотеки.

Прежде чем переходить к написанию методов API для осуществления поиска в базах данных MySQL опишем методы установки соединения и выполнения запросов. Все методы для удобства объединим в класс DB.

 

 

 

 

 

Открытые свойства класса DB.

 

 

 

 

 

 

 

 

 

 

 

Свойство

 

Тип

 

 

 

Описание

 

 

 

 

 

 

 

 

 

 

 

$connection

 

resource

 

 

Указатель на соединение с MySQL

 

 

$dsn

 

array

 

 

Данные соединения:

 

 

 

 

 

 

 

host – спецификация сервера (имя_сервера*:порт+)

 

 

 

 

 

 

 

database – название базы данных

 

 

 

 

 

 

 

username – имя пользователя

 

 

 

 

 

 

 

password – пароль для логина

 

 

 

 

 

 

Открытые методы класса DB.

 

 

 

 

 

 

 

 

 

Метод

 

 

 

Описание

 

 

 

 

 

 

 

 

 

connect($dsn)

 

 

 

Установка соединения с базой данных MySQL.

 

 

 

 

 

 

 

 

array $dsn – данные соединения.

 

 

disconnect()

 

 

 

 

 

Отсоединение от базы данных MySQL.

 

 

isError()

 

 

 

 

 

Проверка, является ли результат ошибкой.

 

 

query($query, $params)

 

 

 

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

 

 

 

 

 

 

 

 

string $query – SQL запрос;

 

 

 

 

 

 

 

 

array $params – параметры запроса.

 

 

queryLimit($query,

 

 

 

Генерация ограниченного (лимитированного) запроса.

 

 

 

$from, $count)

 

 

 

int $from – номер строки, с которой начинать выбор;

 

 

 

 

 

 

 

 

int $count – число возвращаемых записей.

 

 

queryOne($query, $params)

 

 

 

Получение значения 1-ой строки 1-ого столбца результата

 

 

 

 

 

 

 

 

запроса.

 

 

queryRow($query, $params)

 

 

 

Получение значений 1-ой строки результата запроса.

 

 

queryCol($query, $params)

 

 

 

Получение значений 1-ого столбца результата запроса.

 

 

queryAssoc($query, $params)

 

 

 

Получение результатов запроса в виде ассоциативного

 

 

 

 

 

 

 

 

массива, используя первый столбец в качестве ключей.

 

 

 

 

 

4

 

Предопределённые константы.

Код состояния (константа)

Описание

 

 

DB_OK

Ошибок нет

DB_ERROR_SYNTAX

Синтаксическая ошибка запроса к базе данных

DB_ERROR_CONSTRAINT

Отсутствует внешний ключ

DB_ERROR_NOT_FOUND

Попытка удалить несуществующий индекс

DB_ERROR_ALREADY_EXISTS

Попытка создания уже существующей таблицы

DB_ERROR_UNSUPPORTED

Запрошенная операция не поддерживается

DB_ERROR_MISMATCH

Число параметров запроса не совпадает с требуемым

DB_ERROR_TRUNCATED

Возвращаемые данные были получены не полностью

DB_ERROR_INVALID

Ошибка входных данных запроса к базе данных

DB_ERROR_INVALID_DSN

Неверно указаны данные соединения

DB_ERROR_INVALID_NUMBER

Попытка записи нечислового значения в числовое поле

DB_ERROR_INVALID_DATE

Неверный формат даты в запросе к базе данных

DB_ERROR_DIVZERO

Ошибка деления на ноль при запросе к базе данных

DB_ERROR_NODBSELECTED

Не указана база данных при попытке соединения

DB_ERROR_CANNOT_CREATE

Невозможно создать таблицу или файл базы данных

DB_ERROR_CANNOT_DROP

Невозможно удалить таблицу или файл базы данных

DB_ERROR_NOSUCHTABLE

Попытка обращения к несуществующей таблице

DB_ERROR_NOSUCHFIELD

Попытка обращения к несуществующему полю

DB_ERROR_NOSUCHDB

Попытка доступа к несуществующей базе данных

DB_ERROR_NEED_MORE_DATA

Необходимо больше данных

DB_ERROR_CONNECT_FAILED

Невозможно установить соединение с базой данных

DB_ERROR_ACCESS_VIOLATION

Ошибка доступа к таблице или файлу базы данных

Установка соединения с базой данных.

Ниже приведены методы класса DB, выполняющие соединение и разъединение с базой данных. Для этих целей в методе используются функции PHP mysql_connect, mysql_error, mysql_select_db и mysql_close. В

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

1 public function connect($dsn)

2{

3$this->dsn = $dsn;

5// Подготовка параметров подключения к базе данных

6$params = array();

7$params[0] = $dsn['host'] ? $dsn['host'] : 'localhost';

8if($dsn['port'])

9$params[0] .= ':' . $dsn['port'];

10$params[] = $dsn['username'] ? $dsn['username'] : null;

11$params[] = $dsn['password'] ? $dsn['password'] : null;

13// Попытка установки подключения

14$this->connection = @call_user_func_array('mysql_connect', $params);

5

15

16// Ошибка установки соединения

17if(!$this->connection)

18{

19if(($err = @mysql_error()) != '') {

20

return $this->Error(DB_ERROR_CONNECT_FAILED, $err);

21

else

22

return $this->Error(DB_ERROR_CONNECT_FAILED);

23

}

24

 

25// Выбор базы данных

26if($dsn['database'])

27{

28if(!@mysql_select_db($dsn['database'], $this->connection))

29

return $this->Error(DB_ERROR_NOSUCHDB);

30

else

31

return DB_OK;

32}

33}

34

35public function disconnect()

36{

37$ret = @mysql_close($this->connection);

38$this->connection = null;

39return $ret;

40}

Выполнение SQL запросов.

Перед непосредственным выполнением запросов к базе данных, он должен быть специальным образом обработан для защиты от одного из самых распространённых способов взлома сайтов – SQL инъекций.

SQL инъекции являются попытками злоумышленников внедрить произвольный SQL код в запрос. Внедрение SQL, в зависимости от типа используемой СУБД и условий внедрения, может дать возможность атакующему выполнить произвольный запрос к базе данных (например, прочитать содержимое любых таблиц, удалить, изменить или добавить данные), получить возможность чтения и/или записи локальных файлов и выполнения произвольных команд на атакуемом сервере.

Атака типа внедрения SQL может быть возможна из-за некорректной обработки входных данных, используемых в SQL-запросах.

Допустим, серверное ПО, получив входной параметр, использует его для создания SQL-запроса. Рассмотрим следующий PHP скрипт:

1$id = $_REQUEST['id'];

2$res = mysql_query("SELECT * FROM news WHERE id_news = $id");

Если на сервер передан параметр, равный «5», то выполнится следующий SQL-запрос:

SELECT * FROM news WHERE id_news = 5

6

Но если злоумышленник передаст в качестве параметра строку «-1 OR 1=1», то выполнится запрос:

SELECT * FROM news WHERE id_news = -1 OR 1=1

Таким образом, изменение входных параметров путѐм добавления в них конструкций языка SQL вызывает изменение в логике выполнения SQL-запроса (в данном примере вместо новости с заданным идентификатором будут выбраны все имеющиеся в базе новости, поскольку выражение 1=1 всегда истинно).

Чтобы внедрение кода было невозможно, для некоторых СУБД, в том числе, для MySQL, требуется брать в кавычки все строковые параметры. В самом параметре заменяют кавычки на \", апостроф на \', обратную косую черту на \\ (экранировать спецсимволы). Реализацию данных операций реализуем встроенными средствами языка PHP и включим в класс DB:

1private function escape($str)

2{

3if(function_exists('mysql_real_escape_string'))

4return @mysql_real_escape_string($str, $this->connection);

5else

6return @mysql_escape_string($str);

7}

Далее приведём код ключевого метода query, а также вспомогательные (приватные) методы класса. Остальные методы выполнения запросов

(queryOne, queryAssoc, queryCol, queryLimit и пр.) базируются именно на методе query. Методу подаётся на вход запрос, в котором места подстановки конкретных значений параметров указываются символом «?», и массив значений подставляемых параметров. Все значения параметров будут соответствующим образом обработаны, подставлены в запрос и окружены кавычками.

1public function query($query, $params = array())

2{

3// Запрос с параметрами

4if(sizeof($params) > 0)

5{

6$sth = $this->escape($query);

7if(DB::isError($sth))

8

return $sth;

9

 

10$ret = $this->execute($sth, $params);

11return $ret;

12}

13// Запрос без параметров (для ускорения выполнения)

14else

15{

16$this->last_parameters = array();

17$result = $this->simple($query);

18if($result === DB_OK || DB::isError($result))

19

return $result;

20else

21{

7

22

$tmp =

new DB_result($this, $result);

23

return

$tmp;

24}

25}

26}

27

 

28

private function execute($stmt, $data = array())

29{

30$stmt = (int)$stmt;

31$data = (array)$data;

32$this->last_parameters = $data;

34if(count($this->prepare_types[$stmt]) != count($data))

35{

36$this->last_query = $this->prepared_queries[$stmt];

37return $this->raiseError(DB_ERROR_MISMATCH);

38}

39

40 $realquery = $this->prepare_tokens[$stmt][0]; 41

42// Обработка параметров запроса и построение запроса

43$i = 0;

44foreach ($data as $value)

45{

46if($this->prepare_types[$stmt][$i] == DB_PARAM_SCALAR)

47

$realquery .= $this->quote($value);

48elseif ($this->prepare_types[$stmt][$i] == DB_PARAM_OPAQUE)

49{

50

$fp = @fopen($value, 'rb');

51

if(!$fp)

52

{

53

return $this->raiseError(DB_ERROR_ACCESS_VIOLATION);

54

}

55

$realquery .= $this->quote(fread($fp, filesize($value)));

56

fclose($fp);

57}

58else

59

$realquery .= $value;

60$realquery .= $this->prepare_tokens[$stmt][++$i];

61}

62

63return $realquery;

64}

65

66private function simple($query)

67{

68$this->last_query = $query;

70// Выполнение запроса без параметров

71if(!$this->options['result_buffering'])

72$result = @mysql_unbuffered_query($query, $this->connection);

73else

74$result = @mysql_query($query, $this->connection);

75

76return DB_OK;

77}

8

Пример использования.

1$dsn = array(

2'host' => 'prepod.mysql:3306',

3'database' => 'prepod_db',

4'username' => 'prepod_admin',

5'password' => 'hfsrwcnt'

6);

7

8 $db = new DB();

9

10// Установка соединения с базой данных

11$connect = $db->connect($dsn);

12if(DB::isError($connect))

13die('Ошибка подключения к базе данных');

15// Выполнение запроса

16$results = $db->queryAssoc('SELECT login, email FROM users WHERE id = ?',

17array($_REQUEST['id']));

18if(DB::isError($result))

19die('Ошибка выполнения запроса к базе данных');

21// Вывод результата

22foreach($result as $login => $email)

23echo $login . ' ' . $email . '<br />';

9