Разширението mysqli - кратко ръководство
29-11-2010
Забелязах, че много рядко някой използва разширението mysqli. Предимствата му пред стария mysql метод са наистина впечатляващи и лично аз още с встъпването на PHP 5 в обръщение започнах да го използвам и на скоро се хванах, че дори съм забравил синтаксиса и принципа на mysql. Ще опиша повечето свойства на разширението, които аз редовно използвам, както и основният му синтаксис.
Разширението mysqli може да се ползва както с интефейс от функции, така и с обектно-ориентиран такъв, което лично за мен е изключително удобно.

Свързване с MySQL базата
Свързването с базата, използвайки обектно-ориентирания интерфейс на mysqli става по следния начин :


<?php
$mysqli = mysqli_init();
$mysqli -> real_connect($db_host, $db_user, $db_pass, $db_name);
?>

Където разбира се на real_connect се подават хоста, потребителя и паролата за базата данни, както и нейното име. От тук нататък променливата $mysqli държи класа с mysql връзката

Прости заявки
Простите заявки в mysqli са с подобен принцип като старите такива, с някой много дребни разлики. За целта се използва метода query, a за извличане както преди fetch_array или fetch_row ето примерна заявка с mysqli :

<?php
$mysqli = mysqli_init();
$mysqli -> real_connect($db_host, $db_user, $db_pass, $db_name);
// Вече сме закачени със сървъра и базата дании, продължаваме със заявката

$mysqli -> query("select name from users");
// Заявката е готова, избрали сме колоната name от users, извличаме данните

while($row = $mysqli -> fetch_aray()) {
print $row['name'] . "<br />\n";
}
// Данните са изведени в while цикъл, затваряме заявката

$mysqli -> close();
?>

<p style="text-align:justify;">Както виждате, с изключение на това, че използвам обектно-ориентираният интерфейс, разликите дотук не са особено големи.

В оригиналната статия в блога ми съм описал и работата с множество заявки, но тъй като не се използва много често тук ще я пропусна.

Готови конструкции /любимата ми част/
<p style="text-align:justify;">За мен т.нар. prepared statements са най-сладкото в mysqli. Бързодействието и сигурността са в пъти повече от класическите заявки. SQL Injection, например, тук е невъзможен..

Готовите конструкции са два основни вида. Такива за извличане на данни и такива за манипулиране с данни. Създаването и използването им е наистина просто. Изпраща се само шаблон на заявката до сървъра, МySQL получава само шаблона, проверява дали е правилно структуриран, парсва го, за да провери дали е смислен и го складира в специален буфер. До тук всичко е като при нормална заявка. Тук обаче MySQL връща специален манипулатор, който по-късно може да бъде използван за обръщане към вече готовият шаблон.

При конструиране на входни променливи се поставя въпросителен знак, който маркира мястото им в SQL заявката : SELECT id, country FROM city WHERE city = ? или INSERT INTO city (id, name) VALUES (?, ?). Изходните променливи се обвързват директно с колоните от резултатите. Процедурите по обвързване леко се различават. Входните трябва да бъдат обвързани преди изпълнението на конструкцията, а изходните - след изпълнението й.

Процесът при входните променливи е следният :

1. Подготовка (парсване) на конструкцията.
2. Обвързване на входните променливи.
3. Присовяване на стойности на обвързаните променливи.
4. Изпълнение на готовата конструкция.


Процесът при изходните променливи е следният:

1. Подготовка (парсване) на конструкцията.
2. Изпълнение на конструкцията.
3. Обвързане на изходните променливи.
4. Извличане на данните в изходните променливи

Изпълнението на готова конструкцията или извличане на данни от такава могат да бъдат повтаряни много пъти докато конструкцията бъде затворена. Готовите конструкции изпълзват следните свойства :

$mysqli -> prepare()
Подготвя конструкцията. Параметри :
- Конструкция

$stmt-> bind_result()
Обвързва променливи с набора от резултати от конструкция. Параметри :
- Променливи

$stmt -> bind_param()
Обвързва променливи с конструкция. Параметри :
- Низ, описващ типа на променливите (s = низ, i = число, d = число с двоична стойност, b = blob)
- Променливи

$stmt -> execute()
Изпълнява готова конструкция

$stmt -> fetch()
Извилича данни в изходни променливи.

$stmt -> close()
Затваря готова конструкция.

И тъй като предполагам, че тази таблица е доста объркваща за някой от Вас - да направим един пример за заявка за манипулация с данни, използваща обвързани входни променливи. Много е лесно :

<?php
$mysqli = mysqli_init();
$mysqli -> real_connect($db_host, $db_user, $db_password, $db_name);

$mysqli -> query("create table alfas " .
"year integer, model varchar(50), accel real)");
// Имаме база данни с таблица alfas и полета year, model и accel

$stmt = $mysqli -> prepare("insert into alfas values(?, ?)");
// Подготвихме готовата конструкция, като стойностите, които ще дадем
// по-късно са заменени с ?

$stmt -> bind_param("isd", $year, $model, $accel);
// Обвързваме променливите като казваме, че ще са integer, string и decimal
// и казваме какви променливи ще използваме

$year = 2001;
$model = "156.2.0 Selespeed";
$accel = 8.6;
$stmt -> execute();
// Подаваме стойности към обвързаните променливи и изпълняваме конструкцията.
// Данните са въведени..

$year = 2003;
$model = "147 2.0 Selespeed";
$accel = 9.3;
$stmt -> execute();
// Подадохме още едни стойности към обвързаните променливи и изпълнихме
// конструкцията. Още един ред данни е въведен.

$year = 2004;
$model = "156 GTA Sportwagon";
$accel = 6.3;
$stmt -> execute();
// Още веднъж същата процедура и имаме още един ред.

$stmt -> close();
?>

Видяхте ли ? Не е толкова трудно. Това е изключително удобно и подредено, когато имате дълги заявки с много променливи за записване. Заявката си е отделно, променливите се закачат отделно. Плюс това ако искате да изпълните една и съща заявка няколко пъти няма нужда да изпълнявате цялата заявка отново и отново в цикъл, а просто пускате шаблона толкова пъти, колкото Ви е нужен, след което го затваряте. Друго предимство е, че ако входните данни не отговоарят на низа с типовете - данните няма да се вкарат. Т.е. това Ви освобождава от постоянно правене на проверки кое е int и кое string ...

Ето един пример за извилчане на данни чрез шаблон :

<?php
$mysqli = mysqli_init();
$mysqli -> real_connect($db_host, $db_user, $db_pass, $db_name);

$stmt = $mysqli -> prepare("select * from alfas order by year");
$stmt -> execute();

$stmt-> bind_result($year, $model, $accel);
// Подаваме променливи, на които да се присвоят стойностите на резултата.

while($stmt -> fetch()) {
print $year . "\n" .
$model . "\n" .
. $accel . "sec\n";
}
?>

В случая обвързваме $year, $model и $accel с колоните на таблицата. Всяко извикване на $stmt -> fetch() променя тези променливи с данните от текущия ред. fetch() в while, разбира се, ще връща true докато не свършат данните.

Общо взето това е. Повечето неща са официално така, някой са от моя стил на писане, но като цяло това е принципа. Ако имате каквито и да е въпроси - очаквам ги.

Оригиналната статия се намира тук. Копирането и извън web-tourist.net не е желателно, освен в случай, че е посочен линк към този урок.


/ Трябва да сте регистриран за да напишете коментар /
От: vik96
20:28 30-11-2010
Супер е урочето :)
BTW: За по-малко писане можете да се свързвате с базата данни чрез:
$mysqli = new mysqli("localhost", "user", "password", "tablica");
От: idevbg
11:05 01-12-2010
Да. vik96 е прав. И това е вариант :)
От: qazxsw
20:40 01-12-2010
Предпочитам да си ползвам mysql като че ли.
От: gLaVoReZa
0:21 02-12-2010
По принцип браво, но има и други важни неща, освен prepared statements. В PDO можеш да правиш undo на заявки, които вече са изпълнени. Предполагам, че това го има и в MySQLi.
От: idevbg
1:18 02-12-2010
"Ще опиша повечето свойства на разширението, които аз редовно използвам, както и основният му синтаксис." :) Пишете за PDO - ще е полезно. Т'ва е кратко ръководство за MySQLi, а доколкото знам undo на заявки няма.
От: NewGuy
12:48 03-12-2010
Аз обаче не разбрах най-важното. Защо трябва да се използва mysqli вместо Mysql? По-бързо ли е?
От: idevbg
13:01 03-12-2010
Много по-бързо и доста по-сигурно и лично за мен по-удобно.
От: qazxsw
4:40 05-12-2010
Ам, MySQL е по-бързо от MySQLi
От: idevbg
16:00 05-12-2010
Ам, хубаво - ползвай си го :)
От: MaLa_NocHe
0:11 06-12-2010
Като идея ми харесва, но не разбрах това:

$stmt-> bind_result($year, $model, $accel);


Къде сме задали стойностите на тези 3 променливи?
От: idevbg
0:12 06-12-2010
Надолу ги задаваш. Присвояваш стойности на тея трите променливи и execute()-ваш заявката. После, ако е нужно - пак.
От: Rado
15:05 10-01-2011
Една много хубава статия по въпроса - http://af-design.com/blog/2009/01/30/php-mysql-vs-mysqli-database-access-metrics/
От: warning_
23:45 30-01-2011
Мерси!
От: t0shk0
4:23 11-07-2012
Аз винаги използвам PDO. Няма значение дали работя с mysql или mysqli
1