Лекція № 17
Тема: Функції РНР для роботи з MYSQL
План
З’єднання РНР-сценаріїв з таблицями MySQL
Вибір бази даних
Обробка помилок
Виконання запитів до БД
Обробка результату запиту
Отримання інформації про результат
З'єднання РНР-сценаріїв з таблицями MYSQL
Основною функцією є mysql_connect(), яка підключає наш сценарій до сервера баз даних і виконує авторизацію користувача.
mysql_connect([string $hostname] [, string $user]
[, string $password])
Всі параметри функції є необов'язковими, оскільки значення за умовчанням можна прописати в конфігураційному файлі php.ini. Якщо ви хочете вказати інші ім'я MySQL-вузла, ім'я користувача і пароль, ви завжди можете це зробити. Параметр $hostname може бути вказаний у вигляді вузол: порт.
Функція повертає ідентифікатор (типу int) з'єднання, вся подальша робота здійснюється тільки через цей ідентифікатор. При наступному виклику функції mysql_connect() з тими ж параметрами нове з'єднання не буде відкрито, а функція поверне ідентифікатор існуючого з'єднання.
Для закриття з'єднання призначена функція mysqI_close(int Sconnection_id). З'єднання можна не закривати — воно буде закрито автоматично при завершенні сценарію. Якщо ви використовуєте більш за одне з'єднання, при виклику mysqI_close() потрібно вказати ідентифікатор з'єднання, яке ви хочете закрити. Знову ж таки, ви можете зовсім не закривати з'єднання — вони будуть закриті автоматично при завершенні сценарію, але пам'ятаєте, що це поганий стиль, тому краще всього закрити з'єднання самостійно.
Якщо ви плануєте використовувати тільки одне з'єднання з базою даних за весь час роботи сценарію, можна не зберігати його ідентифікатор і не указувати ідентифікатор при виклику решти функцій.
Функція mysql_connect() встановлює звичайне з'єднання з базою даних. Проте PHP дозволяє створювати так звані постійні з'єднання — для цього використовується функція mysql_pconnect(). Параметри у цієї функції такі ж, як і у mysql_connect().
У чому ж різниця між звичайним і постійним з'єднанням? Постійне з'єднання не закривається після завершення роботи сценарію, навіть якщо сценарій викликав функцію mysql_close(). З'єднання «прив'язується» до PID нащадка Apache (від імені якого воно і працює) і закривається лише тоді, коли віддаляється процес-власник (наприклад, перезавантаження або завершення роботи сервера Apache).
PHP працює з постійними з'єднаннями приблизно так: при виклику функції mysql_pconnect() PHP перевіряє, чи було раніше встановлено з'єднання. Якщо так, то повертається його ідентифікатор, а якщо немає, відкривається нове з'єднання і також повертається ідентифікатор.
Недоліків у постійних з'єднань практично немає. Постійні з'єднання дозволяють значно понизити навантаження на сервер, а також підвищити швидкість роботи сценаріїв, що використовують базу даних.
При роботі з постійними з'єднаннями потрібно стежити, щоб максимальне число клієнтів Apache не перевищувало максимального числа клієнтів MYSQL, тобто параметр MaxCIient (у файлі httpd.conf) повинен бути менше або рівний параметру max_user_connection (параметр MYSQL).
Вибір бази даних
Функція mysql_select_db(string $db [, int $id]) вибирає базу даних, з якою працюватиме сценарій. Якщо відкрито не більш за одне з'єднання, можна не указувати параметр $id.
Приклад підключення до бази даних:
// Намагаємося встановити з'єднання
if(!mysql_connect($SERVER,$USER,$PASSWD))
{
echo "He можу підключитися до сервера";
exit;
}
// Вибираємо базу даних
mysql_select_db($DB);
Обробка помилок
Якщо відбудеться помилка, ми отримаємо повідомлення "Не можу підключитися до сервера" і все: сценарій завершить свою роботу. Не дуже-то зручно. Перш за все, для себе, тобто для відладки свого сценарію, можна використовувати дві функції:
mysql_errno(int $id) mysql_error(int $id)
Перша функція повертає номер помилки, а друга — повідомлення про помилку. Замість тривіального повідомлення зручніше використовувати наступне:
echo "ERROR ".mysql_errno()." ".mysql_error()."\n";
Тепер вам не потрібно ворожити, із-за чого відбулася помилка — ви відразу побачите повідомлення про помилку.
Виконання запитів до бази даних
Всі запити до поточної бази даних відправляються функцією mysql_query(). Цій функції потрібно передати один параметр — текст запиту. Текст запиту може містити пробільні символи і символи нового рядка (\n). При цьому текст повинен бути складений за правилами SQL.
Приклад запиту:
$r=mysql_query("select * from hbd");
Наступний запит повинен повернути вміст таблиці hbd. Результат запиту привласнюється змінною $г. Результат — це набір даних, який після виконання запиту потрібно обробити певним чином.
Обробка результату запиту
Якщо запит за допомогою функції mysql_query() успішно виконався, то в результаті клієнт отримує набір записів, який може бути оброблений наступними функціями:
mysql_resuIt() — отримати потрібний елемент з набору записів;
mysqI_fetch_array() — занести запис в масив;
mysql_fetch_row() — занести запис в масив;
mysql_fetch_assoc() — занести запис в асоціативний масив;
mysql_fetch_object() — занести запис в об'єкт.
Перш ніж починати розбір отриманого результату, зазвичай буває необхідно визначити кількість записів, що містяться в нім, і полів. Функція mysql_num_rows() дозволяє дізнатися, скільки записів містить наш результат:
$r=mysql_query("select * from hbd");
echo "B таблиці hbd ".mysql_num_rows(Sr)." записів";
Запис складається з полів (грубо кажучи — колонок). Дізнатися, скільки полів містить кожен запис результату, дозволяє функція mysql_num_fieIds():
$r=mysql_query("select * from hbd");
echo "В таблиці hbd ".mysql_num_fields($r)." полів";
Ми вже можемо отримати кількість записів і кількість полів таблиці. Нам залишилося дізнатися значення кожного поля. Це можна зробити за допомогою mysqI_result(int $resuIt, int $row, mixedSfieId). Параметр $row задає номер запису, а $field — ім'я або порядковий номер поля.
Припустимо, що наш запит повернув наступний набір даних:
Email FirstName LastName
ivan@mail.ru Ivan Ivanov
sid@mail.ru Petr Sidorov
Вивести його в браузер дозволяє наступний код:
$rows = mysql_num_rows($r); $cols = mysql_num_fields($r);
echo "<PRE>";
for ($i=0; $i<$rows; $i++) {
for (j=0; $j<$cols; $j++)
echo mysql_result($r, $i, $j)."\t"; echo "\n";
}
echo "</PRE>";
Варто відзначити, що функція mysql_result() універсальна: знаючи кількість записів і кількість полий, можна «обійти» весь результат, але в теж час ця функція достатньо повільна. Тому для обробки великих наборів записів рекомендується використовувати функції, що мають в середині _fetch_, а саме, mysql_fetch_row(), mysql_fetch_array(), і т.д.
Функція mysql_fetch_row(int $res) отримує відразу весь рядок, відповідний поточному запису результату $res. Кожен наступний виклик функції переміщає покажчик запиту на наступну позицію (як при роботі з файлами) і отримує наступний запис. Якщо більше немає записів, то повертається значення false.
Приклад використання:
$r=mysql_query("select * from hbd where month=\"$bd_m\" and
day=\"$bd_d\");
for ($i=0; $i<mysql_num_rows($r);
{
$f=mysql_fetch_row($r);
echo $f;
}
Примітка. Звернете увагу на рядок запиту — текстові значення полів обов'язково повинні бути в лапках — це вимога MYSQL.
Використовувати функцію mysql_fetch_row() не завжди дуже зручно, оскільки значення всіх полів одного запису знаходяться все в одному рядку. Набагато зручніше використовувати функцію mysql_fetch_array(), що повертає асоціативний масив, ключами якого будуть імена полий.
Примітка.
Функція mysql_fetch_array(int $res [, int Sresult_type]) повертає не асоціативний масив, а масив, заданий необов'язковим параметром $result_type.
Параметр $resuly_type може приймати значення:
MYSQL_ASSOC — повертається асоціативний масив;
MYSQL_NUM — повертається масив з числовими індексами (як у функції mysql_fetch_row());
MYSQL_BOTH — повертається масив з подвійними індексами, тобто виможете працювати з ним, як з асоціативним масивом і як із списком.MYSQL_BOTH — це значення за умовчанням параметра Sresult_type.
У PHP є одна функція, яка повертає «чистий» (з одним індексом) асоціативний масив, — mysql_fetch_assoc(int Sres). Ця функція - просто синонім для mysql_fetch_array(Sres, MYSQL_ASSOC).
Приклад використання функції mysql_fetch_array():
$r=mysql_query("select * from hbd where month=\"$bd_m\" and
day=\"$bd_d\");
for ($i=0; $i<mysql_num_rows($r); $i++)
{
$f=mysql_fetch_array($r);
echo "$f[email]$f[name] $f[month] $f[day] $f[sex] <br>";
}
Як бачите, використовувати функцію mysql_fetch_array() набагато зручніше, ніж mysql_fetch_row().
Отримання інформації про результат
Ми розглянули практично всі необхідні вам для роботи функції. Проте PHP надає ще декілька корисних функцій, які дозволяють дізнатися інформацію про результат.
Функція mysql_field_name(int Sresult, int Soffset) повертає ім'я поля, що знаходиться в результаті $result з номером $offset (нумерація починається з 0). Іншими словами, функція повертає ім'я поля з номером $offset.
Функція mysql_field_type(int $result, int Soffset) повертає тип поля з номером $offset в результаті $result (номер задається щодо результату, а не таблиці).
Функція mysqI_field_flags(int $result, int $offset) повертає перераховані через пропуск прапори (модифікатори), які є у поля з номером $offset. Всі підтримувані MYSQL прапори представлені в табл.
Прапор
Опис

not_Null
Поле не може містити невизначеного значення (NULL), тобто поле повинне явно ініціалізувати

Primary_Key
Поле буде первинним ключем — ідентифікатором запису, по якому можна однозначно ідентифікувати запис

auto_increment
При вставці нового запису значення цього поля буде автоматично збільшено на одиницю, тому в таблиці ніколи не буде двох записів з однаковим значенням цього поля

UniqueJ<ey
Поле повинне містити унікальне значення

Multipie_Key
Індекс

Blob
Поле може містити бінарний блок даних

Unsigned
Поле містить беззнакові числа

Zerofill
Замість пропусків використовуються символи з кодом \0

Binary
Поле містить двійкові дані

enum
Поле може містити один елемент з декількох можливих (елемент перерахування)

timestamp
У полі автоматично заноситься поточна дата і час при його модифікації


Функція mysql_field_flags() повертає прапори у вигляді рядка, в якому прапори розділяються пропусками.
Зараз розглянемо повноцінний приклад виведення вмісту таблиці і оформлення у вигляді таблиці HTML (див. лістинг ):
Лістинг. Виведення вмісту таблиці БД у вигляді HTML-таблиці
<?
$SERVER = "localhost"; $USER = "user"; $PASSWD = "12345"; $DB = "my_db";
// Підключаємося
if ( !mysql_connect($SERVER,$USER,$PASSWD) )
{
echo $HEAD;
echo $CP;
echo $BODY;
echo "<h2>$ERROR</h2>";
echo "</body></html>";
exit;
// Вибираємо базу даних mysql_select_db($DB);
// Виводиться заголовок таблиці
echo "<table border=l width=100% bgcolor=gold>"; echo "<tr><td>E-mail</td><td>MMH</td><td>MecHU</td>"; echo "<td>Чиcлo</td><td>Пoл</td></tr>";
// Запит select * from hbd $r=raysql_query("select * from hbd");
// Виводимо таблицю
for ($i=0; $i<mysql_num_rows($r); $i++)
{
echo "<tr>";
$f=mysql_fetch_array($r);
echo "<td>$f [email]</tdxtd>$f [name]</tdXtd>$f[month]</td>"
echo "<td>$f[day]</tdxtd>$f[sex]</td>" ;
echo "</tr>";
}
echo "</table></body></html>"
?>

Мал. Виведення сценарію, що відображає таблицю
Ще одна корисна функція, яка може пригодиться в нагоді вам при написанні ваших сценаріїв, — це функція mysql_list_tables(string $db [, int connect_id]). Функція повертає ідентифікатор результату (одна колонка), що містить імена всіх таблиць у вказаній базі даних. Другий параметр, як завжди, це ідентифікатор з'єднання:
$r = mysql_list_tables("hbd");
while($row = mysql_fetch_row($r))
{
echo $row."\n";
}