Использование ext/mysqli: Обзор и подготовленные выражения

1. Предполагаемая аудитория

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

Направьте внимание на то, что в конце статьи имеются сноски для объяснения неких утверждений и словарь определений.

Аннотации по установке PHP и MySQL выходят за рамки данной статьи;

Для получения инфы об установке PHP 5, посетите http://www.php.net/installation
Информация о компиляции PHP 5 c поддержкой ext/mysqli доступна по адресу http://www.php.net/mysqli
За информацией по установке MySQL 4.1.2 либо выше, обращайтесь на http://www.mysql.com/doc/en/Installing.html

2. Введение

Начиная с середины 90х, ext/mysql служило главным мостом меж PHP и MySQL. Хотя в нем имелись недочеты и препядствия росли с возрастом, в общем, ext/mysql делал свое дело хорошо и шел в ногу с переменами как в PHP, так и в MySQL.

Но с возникновением PHP 5 и MySQL 4.1 все поменялось – начали создаваться несколько довольно широких трещинок.

В ext/mysql имелись «плюсы, оказавшиеся недочетами»: сначала это mysql_pconnect() [1] , подключение по дефлоту и автоматическое подключение [2]. Не считая того, проявились несовместимости меж функциями ext/mysql и теми, что поддерживались клиентской библиотекой MySQL, на которой основаны и ext/mysql, и ext/mysqli.

В попытке поправить эти расхождения, Георг Рихтер сделал еще одно расширение PHP 5, которое поддерживает новые способности MySQL 4.1+. Это расширение получило заглавие ext/mysqli, где ‘i’ подменяет одно из слов: improved(улучшенное), interface(интерфейс), ingenious(изобретательное), incompatible(несовместимое) or incomplete(неполное). [3]

2.1 Главные цели

Некими из главных целей сотворения нового расширения были:

Простота использования. Код ext/mysql стал очень сложным и хаотичным. Значимая модернизация функциональности MySQL востребовала способности подключения и отключения тех либо других частей зависимо от версии клиентской библиотеки. Другие препядствия добивались конфигурации функциональности зависимо от операционной системы.
Наилучшая сопоставимость. Расширение должно было более аккуратненько использовать клиентскую библиотеку MySQL, чтоб будущие усовершенствования библиотеки проще поддерживались в PHP.
Оборотная сопоставимость. Хотя сопоставимость меж ext/mysql и ext/mysqli не безупречна, были приложены значимые усилия для облегчения портирования приложений с ext/mysql на ext/mysqli.

2.2 Главные способности

Ext/mysqli поддерживает новые способности, показавшиеся в последних версиях MySQL, и предлагает новые функции.

Главные способности расширения:

Процедурный интерфейс, очень схожий на интерфейс ext/mysql.
Объектно-ориентированный интерфейс, который позволяет использовать стиль, более обычный и расширяемый, ежели процедурный интерфейс.
Поддержка нового бинарного протокола MySQL, введенного в версии 4.1. (Новый протокол более эффективен, чем старенькый, и поддерживает более широкий набор способностей, к примеру приготовленные выражения).
Поддержка полного набора способностей клиентской библиотеки MySQL C, в том числе установки сложных характеристик соединения при помощи mysqli_init() и других функций. Не считая того, расширение имеет поддержку дополнительных функций мониторинга, отлова ошибок, управления загрузкой и репликации.

2.3 Для чего перебегать?

Не считая получения доступа к дополнительному функционалу MySQL 4.1+, для чего же стоит перебегать на внедрение ext/mysqli?

В дополнение к упомянутому функционалу, ext/mysqli имеет несколько существенных преимуществ:

Приметно большая скорость. Усовершенствования, как в расширении, так и в MySQL, ускорили большая часть операций, время от времени достигая 40-кратного роста производительности по сопоставлению с ext/mysql.
Усиленная безопасность. В ранешних версиях MySQL RDBMS (см. Словарь определений в конце статьи – прим. переводчика), была возможность отловить хэш слабенького пароля в сети и потом воссоздать пароль юзера. Новенькая процедура аутентификации еще прочнее и повторяет устойчивые к атакам механизмы авторизации таких инструментов как SSH.

2.4 Предупреждения и неожиданности

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

Подключение к базе данных по дефлоту. Если вы очевидно не подключитесь к ней, ext/mysqli не сделает этого за вас.
Соединение по дефлоту (link). Нужно очевидно обращаться к соединению с сервером базы данных, которое вы желаете использовать, если вы работаете с ext/mysqli через процедурный интерфейс, к примеру mysqli_query($link, $query);

3. Покажите мне код!

Сейчас, когда вы понимаете, что поменялось, мы начнем рассматривать код, который показывает, как смотрится и работает новое расширение. Весь самостоятельный код, приведенный в этой статье, употребляет базу данных «world», которая безвозмездно доступна на веб-сайте http://www.mysql.com/documentation/index.html.

3.1 Базисное внедрение

Вот обычной скрипт, который соединяется с сервером MySQL, отправляет запрос серверу при помощи этого соединения, выводит результаты запроса и потом высвобождает результирующее огромное количество запроса и закрывает соединение.

Приведенный сценарий должен вывести что-то вроде:

Очень большие городка:
Mumbai (Bombay) (10500000)
Seoul (9981619)
Sao Paulo (9968485)
Shanghai (9696300)
Jakarta (9604900)

Как видно из кода, ext/mysqli и ext/mysql могут быть очень похожи. Единственным значимым различием будет то, что процедурный стиль ext/mysqli несколько более «многословен».

Заметьте, что без проверки на ошибки приведенный скрипт мог бы дать сбой в любом месте и вывести юзеру отвратительное сообщение об ошибке.

3.2 Внедрение объектно-ориентированного интерфейса

Объектно-ориентированный интерфейс предоставляет мало более лаконичный и наименее восприимчивый к ошибкам способ использования ext/mysqli. Код, приведенный ниже, производит те же деяния, что и предшествующий, но, имеются несколько главных различий, на которые стоит направить внимание:

Нам не надо очевидно задавать соединение, применяемое в наших командах. Информация о подключении содержится в наших объектах $mysqli и $result и доступна при вызове соответственных способов.
Когда делается подборка из результирующего набора данных запроса с внедрением fetch_assoc(), не надо очевидно задавать идентификатор применяемого результирующего набора. Также как и информация о подключении, он содержится в объекте $result.
query(‘SELECT Name, Population FROM
City ORDER BY Population DESC LIMIT 5′)) {
print(«Очень большие городка:n»);
/* Избираем результаты запроса: */
while( $row = $result->fetch_assoc() ){
printf(«%s (%s)n», $row['Name'], $row['Population']);
}
/* Освобождаем память */
$result->close();
}
/* Закрываем соединение */
$mysqli->close();
?>

4. Приготовленные выражения

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

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

Приготовленные выражения можно использовать 2-мя методами: с данными параметрами и с данными плодами.

4.1 С данными параметрами

Приготовленные выражения с данными параметрами позволяют создавать шаблоны запросов и хранить их на сервере MySQL. Когда необходимо сделать запрос, данные, заполняющие шаблон, отправляются серверу MySQL, где вполне сформированный запрос и производится.

Основной процесс сотворения и использования приготовленных выражений с данными параметрами прост.

Создается шаблон запроса и посылается серверу MySQL. Сервер его получает, инспектирует его правильность, чтоб убедиться, что он имеет смысл, и сохраняет его в особом буфере. Потом сервер возвращает идентификатор, который может быть в предстоящем применен для воззвания к приготовленному выражению.

Когда необходимо сделать запрос, данные, заполняющие шаблон, отправляются серверу MySQL и вполне сформированный запрос производится.

В этом процессе заключено несколько очень принципиальных деталей.

Тело шаблона отсылается серверу MySQL только один раз. Для выполнения выражения посылаются только данные, нужные для наполнения шаблона.

Большая часть работы по проверке и обработке запроса проделывается только один раз, заместо того, чтоб делать это всякий раз.

Не считая того, для запросов, которые содержат маленькое количество дынных, расходы очень уменьшены. К примеру, если у вас есть запрос типа:

INSERT INTO City (ID, Name) VALUES (NULL, ‘Calgary’);

то всякий раз при выполнении запроса необходимо отослать только около 16 б заместо обыденных 60 либо более б. (Эти приближенные числа включают расходы на все данные вроде идентификатора приготовленного выражения, длины данных запроса – для безопасности бинарных данных – и т.д., но не включают расходы на строчку запроса.)

Данные запроса не должны проходить через функции вроде mysql_real_escape_string(), чтоб убедиться, что нет опасности атаки «SQL-впрыска» [4] Заместо этого, клиент и сервер MySQL работают так, чтоб убедиться, что посланные данные неопасно обработаны при их комбинировании с приготовленным выражением.

Шаблон запроса смотрится как-то так:

INSERT INTO City (ID, Name) VALUES (?, ?);

Символ ‘?’ можно использовать в большинстве мест, где употребляются символьные данные, к примеру запрос может быть переделан из

SELECT Name FROM City WHERE Name = ‘Calgary’;

в

SELECT Name FROM City WHERE name = ?;
prepare(«INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)»);
$stmt->bind_param(‘sssd’, $code, $language, $official, $percent);
$code = ‘DEU’;
$language = ‘Bavarian’;
$official = «F»;
$percent = 11.2;
/* выполнение приготовленного выражения */
$stmt->execute();
printf(«%d Row inserted.n», $stmt->affected_rows);
/* Закрытие соединения и выражения*/
$stmt->close();
/* Очистить таблицу CountryLanguage */
$mysqli->query(«DELETE FROM CountryLanguage WHERE Language=’Bavarian’»);
printf(«%d Row deleted.n», $mysqli->affected_rows);
/* Закрыть подключение */
$mysqli->close();
?>

Направьте внимание на то, что первым параметром bind_param() является маленькая строчка. Это строчка формата, применяемая для определения того, как объявленные характеристики должны быть интерпретированы.

В случае вышеприведенного сценария ‘sssd’ значит, что значения первых 3-х характеристик $code, $language и $official будут посланы как строчки, а 4-ый параметр $percent будет содержать значения типа double с плавающей запятой.

Для каждой заявленной переменной в bind_param(), должна быть своя буковка в строке формата, которая значит, как переменная будет выслана. К примеру

$stmt->bind_param(‘s’, $foo);
$stmt->bind_param(‘si’, $foo, $bar);
$stmt->bind_param(‘sid’, $foo, $bar, $baz);

Объявление типов обеспечивает то, что расширение mysqli знает, как зашифровать данные для большей эффективности.

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

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

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

Идентификатор типа Тип столбца
i Все INT типы
d DOUBLE и FLOAT
b BLOB’ы
s Другие типы

4.2 С данными плодами

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

Процесс объявления такой:

Сделать запрос.
Попросить сервер MySQL заготовить запрос.
Привязать переменные PHP к столбцам в заготовке запроса.
Вынудить сервер MySQL выполнить запрос.
Запросить добавление нового ряда данных в привязанные переменные.

Вот обычный кусок кода, иллюстрирующий процесс:

prepare(«SELECT Code, Name FROM Country ORDER BY Name LIMIT 5″)) {
$stmt->execute();
/* Привязывание переменных к заготовке */
$stmt->bind_result($col1, $col2);
/* Подборка значений */
while ($stmt->fetch()) {
printf(«%s %sn», $col1, $col2);
}
/* Закрытие оператора $stmt->close();
}
/* Закрытие соединения */
$mysqli->close();
?>

4.3 Внедрение данных характеристик и результатов вкупе

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

prepare(«SELECT Code, Name
FROM Country WHERE Code LIKE ? LIMIT 5″)) {
$stmt->bind_param(«s», $code);
$code = «C%»;
$stmt->execute();
/* Объявление переменных для заготовленного выражения*/
$stmt->bind_result($col1, $col2);
/* Подборка значений */
while ($stmt->fetch()) {
printf(«%s %sn», $col1, $col2);
}
/* Закрытие выражения */
$stmt->close();
}
/* Закрытие подключение */
$mysqli->close();
?>

5. Резюме

В этой статье мы привели обзор способностей и архитектуры ext/mysqli, также короткое изложение истории его развития. К этому моменту вы должны осознавать, как использовать и получать выгоду от приготовленных выражений MySQL и должны ощущать удобство использования объектно-ориентированного интерфейса к ext/mysqli.

6. Словарь определений

ext/mysql – старенькое расширение PHP для работы с MySQL. Не поддерживает всех способностей MySQL версий 4.1 и выше.

ext/mysqli – новое расширение PHP 5 для работы с MySQL. Поддерживает способности MySQL версий от 3.22 до 5.0

Клиентская библиотека MySQL – Компонент MySQL RDBMS (MySQL Relational DataBase Management System – Система управления реляционной базой данных MySQL – прим. переводчика), который позволяет программкам разговаривать с RDBMS.

Сервер MySQL – Компонент MySQL RDBMS, который обрабатывает и отвечает на запросы, управляет файловым представлением данных снутри базы и т.д.

[1] – Функция mysql_pconnect() была предназначена для предоставления механизма уменьшения издержек на установление и разрыв соединений с сервером MySQL. К огорчению, из-за взаимодействия меж архитектурами сервера Apache и PHP, большой трафик на веб-сайте, использующем pconnect, мог стремительно загрязнить сервер MySQL огромным количеством неиспользуемых соединений, которые мешали активным соединениям получать доступ к базе данных.

[2] – Способности автоматического соединения позволяли определенным вызовам функций автоматом соединяться с базой данных (если верная информация о соединении находилась в конфигурационном файле php.ini). Возможность соединения по дефлоту работала по последующему принципу. Последнее открытое соединение с базой MySQL становится применяемым соединением, если параметр соединения не был очевидно указан в аргументах функции.

[3] – Это расширение все еще находится в стадии разработки. В то время как набор способностей ядра должен быть вправду размеренным, ни MySQL 4.1, ни PHP 5.0 не имеют размеренных релизов (статья появилась до выхода PHP 5.0.0 – прим. переводчика). Также, дополнительный набор способностей, который не очень аккуратненько употребляет клиентскую библиотеку MySQL, все еще дорабатывается.

[4] – Атаки типа «SQL-впрыск» вероятны, когда данные входят в запрос, заставляя его совершать внезапные и/либо злостные деяния. Пусть, для примера, дан обычный запрос в PHP скрипте типа «DELETE FROM grades WHERE class_name=’test_$class’». Атакующий может получить контроль над переменной $class и получить возможность an attacker who can gain control over the value of $class can force unintended deletes to occur by changing the value of $class to something like «oops’ or class_name LIKE ‘%’».

7. Об создателях

Зак Грэнт (Zak Greant) – проф заступник концепции Open Source, писатель и программер. Он работает в MySQL AB пропагандистом Общества. Зак поддерживает оба расширения PHP для работы с MySQL и является соавтором PHP Functions Essential Reference.

Георг Рихтер (Georg Richter) – создатель расширения mysqli. Он также поддерживает расширения mysql и ncurses. Он работает в MySQL AB Старшим Разработчиком и является членом Apache Software Foundation.

Аналогичный товар: Комментирование на данный момент запрещено, но Вы можете оставить ссылку на Ваш сайт.

Комментарии закрыты.