Лекція № 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"; }