nmk

Лекція 11 (2 години). Підключення бази даних у PHP (PDO)

План лекції

  1. Варіанти підключення до MySQL в PHP: від старого mysql_connect до сучасного PDO.
  2. Клас PDO (PHP Data Objects): переваги, безпека та універсальність.
  3. Створення об’єкта підключення (DSN, логін, пароль, обробка помилок try-catch).
  4. Налаштування файлу конфігурації db.php.

Перелік умовних скорочень

Вступ

Ми навчилися створювати базу даних та таблицю users через графічний інтерфейс phpMyAdmin (Лекція 10). Але наша кінцева мета — навчити PHP-код спілкуватися з цією базою без ручного втручання людини. Скрипт повинен вміти автоматично додавати туди користувачів із форми реєстрації. У цій лекції ми створимо “Міст” між вашим вебзастосунком та сервером MySQL за допомогою сучасного стандарту PDO.


1. Еволюція підключень: від mysql_* до PDO

Історично в PHP існувало кілька способів “поговорити” з БД:

  1. Старий процедурний драйвер (Функції mysql_*): Наприклад, mysql_connect(). Він був вкрай небезпечним (вразливим до ін’єкцій) і його повністю видалили з сучасних версій PHP 7+. Ніколи не використовуйте його і не копіюйте старий код із форумів з цією приставкою!
  2. Розширення MySQLi (Improved): Продовження старого підходу. Швидке, підтримує як об’єктний, так і процедурний стиль. Але створене виключно для баз MySQL. Якщо ви завтра захочете перевести сайт на PostgreSQL — вам доведеться переписувати весь код підключення з нуля.
  3. PDO (PHP Data Objects): Поточний світовий стандарт і найкраща практика. Це повністю об’єктно-орієнтований інтерфейс.

2. Переваги PDO

3. Створення об’єкта підключення (DSN)

Для підключення за допомогою PDO нам необхідні 4 параметри:

  1. Хост (Host): Де знаходиться сервер бази? Зазвичай це localhost (або 127.0.0.1), оскільки база лежить на тому ж комп’ютері, що й PHP-скрипт.
  2. Ім’я Бази (Database Name): Назва “шафи”, яку ми створили в phpMyAdmin (наприклад, task_manager).
  3. Користувач (Username): Логін для доступу до самої MySQL. За замовчуванням в XAMPP це завжди root.
  4. Пароль (Password): Пароль адміністратора бази. В XAMPP за замовчуванням він порожній "" (просто пустий рядок), а в серверах MAMP (на Mac) зазвичай це "root".

Всі ці налаштування (крім логіна й пароля) об’єднуються в один спеціальний рядок, що називається DSN (Data Source Name): mysql:host=localhost;dbname=task_manager;charset=utf8mb4

Процес з’єднання та Обробка винятків (try/catch)

Що станеться, якщо ми помилимося в паролі або сервер бази “впаде”? PHP видасть на екран (користувачу) страшну Fatal Error (Uncaught PDOException: Access denied for user...), де будуть світитися системні шляхи вашого комп’ютера. Це провал безпеки.

Щоб “перехопити” можливу помилку підключення, використовується конструкція try-catch (Спробуй - Спіймай):

<?php
// Спроба виконати небезпечний код
try {
    // Формуємо DSN рядок для драйвера MySQL
    $dsn = 'mysql:host=localhost;dbname=task_manager;charset=utf8mb4';

    // Створюємо новий Об'єкт PDO (з'єднуємося з БД!)
    // Аргументи: 1) DSN, 2) Логін, 3) Пароль
    $pdo = new PDO($dsn, 'root', '');

    // Кажемо PDO: "Якщо трапиться будь-яка помилка в SQL, негайно генеруй PDOException"
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Якщо цей echo вивівся — підключення пройшло успішно (ПОКИ ТИМЧАСОВИЙ ДЕБАГ)
    // echo "Підключено до Бази Даних успішно!";

} catch (PDOException $e) { // Якщо сталася помилка з'єднання, код стрибає сюди

    // Користувачу показуємо дружнє повідомлення (або логуємо в файл):
    die("На жаль, сервер бази даних тимчасово недоступний. Спробуйте пізніше. Деталі: " . $e->getMessage());
}
?>

4. Налаштування файлу конфігурації db.php

Підключення до бази вам знадобиться майже НА КОЖНІЙ сторінці вашого проєкту (на головній для виведення новин, на сторінці реєстрації, в профілі). Ви не можете копіювати цей блок try-catch у 20 різних файлів! (Пам’ятаємо правило DRY).

Рішення:

  1. Створіть у корені проекту один окремий файл з назвою db.php.
  2. Вставте туди весь код підключення (через try-catch), що описаний вище.
  3. У цьому файлі НЕ ПОВИННО бути жодного HTML-коду, лише чистий PHP.
  4. Тепер, у будь-якому іншому скрипті (наприклад, index.php), на самому початку ви просто робите: require_once 'db.php';

Після цього виклику змінна-об’єкт $pdo стає глобально доступною у вашому index.php, і ви вільні робити з нею будь-які запити до бази!


Висновки

  1. Історичні функції mysql_* є застарілими і вкрай небезпечними. MySQLi - хороша альтернатива тільки для MySQL. PDO — це найбільш універсальний і безпечний сучасний стандарт абстракції БД в PHP.
  2. Для підключення до MySQL через PDO необхідно знати: Хост, Ім’я бази, Логін та Пароль (Реквізити БД). Ці дані форматуються в DSN рядок.
  3. Процес підключення (фактично відкриття “сокета” до іншого сервера) є “тонким льодом”, який гарантовано колись зламається (наприклад БД зависне). Його обов’язково треба обгортати конструкцією лову помилок try-catch, щоб користувачі не бачили системних паролів (PDOException).
  4. Логіку підключення обов’язково треба виносити в окремий конфігураційний файл db.php (базовий приклад Рефакторингу та дотримання DRY).

Джерела

  1. Документація класу PDO: https://www.php.net/manual/ru/class.pdo.php
  2. Рядок підключення DSN (особливості): https://www.php.net/manual/ru/ref.pdo-mysql.connection.php

Запитання для самоперевірки

  1. Поясніть сутність терміну “Абстракція підключень” в PDO порівняно з MySQLi? Що доведеться змінити програмісту, якщо бізнес перенесе свій сайт з бази MySQL на базу PostgreSQL в обох випадках технологій підключення?
  2. Яким стандартним атрибутом (кодом) PDO ми змушуємо його при будь-якій дрібній синтаксичній неточності SQL “кидати” об’єкт Exceptions, замість того щоб він продовжував роботу зі зламаними даними “по-тихому” (Warning)?
  3. Чому конфігурація з паролем від БД (напр new PDO('mysql:host...', 'root', 'super_secret')) повинна знаходитися у файлі, що містить виключно код PHP без домішок та розширень у вигляді <!DOCTYPE html>, а закриваючий тег ?> там зовсім не бажано писати? Чим виклик файлу може погрожувати виводу Headers?
  4. Опишіть призначення конструкції try { ... } catch() { ... }. Що конкретно станеться з роботою PHP-скрипта (і виконанням решти коду нижче) якщо ми залишимо new PDO() прямо посеред документу БЕЗ обгортки (try/catch), а Базу Даних вимкнуть з розетки?
  5. Згадайте процес підключення через require_once. Що гарантує суфікс _once, порівняно зі звичайним require? Чому для файлу бази (db.php) саме ця форма підключення є найправильнішою, особливо в складних проєктах на десятки файлів?