PHP

MySQLi — примеры, обертка и основные особенности



Что это

MySQLi(MySQL Improved/улучшенный Mysql) является улучшенной версией старого драйвера PHP MySQL.

Почему нужно

Разработка php_mysql остановилась на поддержке функционала MySQL 4.1.3. Это расширение не поддерживает транзакции, объектный интерфейс, подвержено уязвимостям при подстановке значений в запрос.

О чем пост

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

Позволяют установить выражение единожды, а затем многократно исполнить его с разными параметрами. Помимо этого они позволяют отделить переменные от запроса.
Существует три причины использовать подготовленные выражения:

Это безопаснее, чем оперирование данными внутри строки
Скорость выполнения выше
Так быстрее писать код

Сравнительная таблица MySQLi, PDO и php_mysql



Как это выглядит по-умолчанию

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* проверяем соединение */
if (mysqli_connect_errno()) {
    printf("Ошибка соединения: %s\n", mysqli_connect_error());
    exit();
}

$city = "Ярославль";

/* создаем подготовленное выражение */
if ($stmt = $mysqli->prepare("SELECT District FROM City WHERE Name=?")) {

    /* связываем параметр */
    $stmt->bind_param("s", $city);

    /* исполняем запрос */
    $stmt->execute();

    /* прикрепляем результаты*/
    $stmt->bind_result($district);

    /* выбираем значение */
    $stmt->fetch();

    printf("%s находится в %s\n", $city, $district);

    $stmt->close();
}

/* закрываем соединение */
$mysqli->close();
?>

Результатом будет: "Ярославль находится в России".

И это здорово, но в один-момент меня посетила мысль, что я не хочу писать так каждый раз, чтобы получить результат выполнения запроса. Так и родился класс SimpleMysqli(с php_mysql и pdo кстати такая же штука- много кода, мало дела).

Класс SimpleMysqli

SVN: http://simple-mysqli-class.googlecode.com/svn/trunk/
Подключение к проекту:
require_once("class.simpleDB.php");
require_once("class.simpleMysqli.php");

или настройте ваш autoload на 'class.'.$className.'.php'

Я достаточно много времени работал с DbSimple, поэтому избрал очень похожий синтаксис.
Пример подключения к БД:
$settings=array(
    'server' => 'localhost',
    'username' => 'root',
    'password' => '',
    'db' => 'my_database',
    'port' => 3306,
    'charset' => 'utf8',
);
$db=new simpleMysqli($settings);

Пример выборки:
$query=$db->select('SELECT * FROM test WHERE id >?',1001);
// Ответ:
Array
(
    [0] => Array
        (
            [id] => 1002
            [val] => another
        )

    [1] => Array
        (
            [id] => 1003
            [val] => habra
        )

)

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

Выборка строки: selectRow()
Выборка ячейки: selectCell()
Выборка столбца: selectCol()
Выполнение обновлений: select()
Вставка данных: insert()
Удаление: delete()
Замена: replace()

Запросы select-типов возвращают результат выборки в том или ином виде, все остальные возвращают bool(true/false). В случае необходимости получения количества обновленных столбцов или количества выбранных строк можно обратиться к публичному члену $queryInfo, который содержит массив следующего вида:
array(
    'affected_rows' => ,
    'insert_id' => ,
    'num_rows' => ,
    'field_count' => ,
    'sqlstate' => ,
);

Подготовка выражений на клиенте

Довольно большой неприятностью могут встать выборки типа:
SELECT * FROM `test` WHERE id IN(1,2,3,4,...,101)

По-умолчанию вам предлагается либо всегда точно знать количество заменителей и писать запрос вида:
SELECT * FROM `test` WHERE id IN(?,?,?,?,...,?)

либо работать со строкой, что не безопасно.

Для таких случаев я ввел дополнительный плэйсхолдер %s, который корректно решает непрятности с массивами в рамках идеологии подготовленных выражений. Важно: класс в таком случае не работает со строкой. Он добавляет члены массива как аргументы и заменяет %s на нужное количество "?". Безопасность не страдает.
Пример:
$arr=array(1,2,3);
$query=$db->select('SELECT * FROM test WHERE id IN(%s)',$arr);
// эквиваленто:
$query=$db->select('SELECT * FROM test WHERE id IN(?,?,?)',1,2,3);


Транзакции

Класс также реализует транзакции:
        $this->db_localhost->transactionStart();
        $this->db_localhost->simpleQuery('DELETE from table');
        $this->db_localhost->simpleQuery('DELETE from another_table');
        $this->db_localhost->transactionCommit();

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

PS

Пожалуйста, не пользуйтесь php_mysql.
Теги:
MySQLi
Добавлено: 17 Августа 2013 02:31:19 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...