Практическое руководство по PHP и MySQL для начинающих

Раздел: Программирование -> Обучение

Основные способы подключения PHP к MySQL

В данном разделе рассматриваются три подхода к установке соединения с базой данных MySQL из PHP: PDO, mysqli в процедурном стиле и mysqli в объектно-ориентированном стиле. Каждый вариант имеет свои особенности и подходит для разных сценариев.

Какое решение является наиболее современным и безопасным?

PDO (PHP Data Objects) - это универсальный интерфейс для работы с базами данных, поддерживающий множество СУБД и обеспечивающий защиту от SQL-инъекций через подготовленные запросы.

$dsn = 'mysql:host=localhost;dbname=test;charset=utf8mb4';
$user = 'root';
$password = '';
$options = [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
try {
    $pdo = new PDO($dsn, $user, $password, $options);
    echo 'Соединение установлено успешно';
} catch (PDOException $e) {
    echo 'Ошибка соединения: ' . $e->getMessage();
}

View quiz php (просмотр теста php)

Код создаёт объект PDO с параметрами подключения. Опция ATTR_ERRMODE включает исключения при ошибках, что упрощает отладку. ATTR_DEFAULT_FETCH_MODE задаёт формат возврата данных по умолчанию (ассоциативный массив).

Типичные проблемы и их решения

  • Ошибка SQLSTATE[HY000] [1045] - неверный логин или пароль. Проверьте учётные данные.
  • Ошибка SQLSTATE[HY000] [2002] - не удаётся подключиться к серверу. Убедитесь, что MySQL запущен и хост указан верно.
  • Исключение PDOException при неправильном DSN - проверьте синтаксис строки подключения.

Как выполнить подключение с помощью процедурного mysqli?

Процедурный стиль mysqli использует функции, такие как mysqli_connect(). Этот метод подходит для простых скриптов и быстрого прототипирования.

$link = mysqli_connect('localhost', 'root', '', 'test');
if (!$link) {
    die('Ошибка соединения: ' . mysqli_connect_error());
}
echo 'Соединение установлено';
mysqli_close($link);

уроки php mysql (уроки по php и mysql)

Функция mysqli_connect() возвращает дескриптор соединения. При неудаче возвращает false, а ошибка доступна через mysqli_connect_error(). Важно закрывать соединение явно.

Типичные ошибки при использовании процедурного mysqli

  • Забывают проверить результат соединения перед дальнейшей работой.
  • Не указывают кодировку - рекомендуется вызывать mysqli_set_charset($link, 'utf8mb4').
  • Ошибка Warning: mysqli_connect(): (HY000/1045) - те же причины, что и для PDO.

Как подключиться через объектно-ориентированный mysqli?

Объектно-ориентированный стиль предлагает класс mysqli с методами для работы с соединением и запросами. Это более структурированный подход.

$mysqli = new mysqli('localhost', 'root', '', 'test');
if ($mysqli->connect_error) {
    die('Ошибка соединения: ' . $mysqli->connect_error);
}
echo 'Соединение установлено';
$mysqli->close();

Конструктор mysqli бросает исключение? По умолчанию нет - ошибка проверяется через свойство connect_error. Начиная с PHP 8.1 можно включить режим исключений.

Частые затруднения с ООП mysqli

  • Путаница между процедурной и объектной версиями функций (например, mysqli_query vs $mysqli->query).
  • Использование $mysqli->connect_error без проверки приводит к ошибке уровня notice, если соединение успешно.
  • Проблемы с кодировкой: нужно вызвать $mysqli->set_charset('utf8mb4').

Выбор конкретного способа зависит от проекта. PDO предпочтителен для новых разработок благодаря гибкости и безопасности. Старые системы часто используют mysqli. В любом случае, следует избегать устаревшего расширения mysql_*.

Расширенные примеры работы с базой данных

Подготовленные запросы в PDO

Пример
$sql = 'SELECT * FROM users WHERE email = :email AND status = :status';
$stmt = $pdo->prepare($sql);
$stmt->execute(['email' => 'user@example.com', 'status' => 1]);
$user = $stmt->fetch();
print_r($user);
Array
(
    [id] => 10
    [name] => Иван Петров
    [email] => user@example.com
    [status] => 1
)

Параметры передаются ассоциативным массивом, что защищает от инъекций. Можно использовать именованные плейсхолдеры (:name) или вопросительные знаки.

Транзакции в PDO

Пример
$pdo->beginTransaction();
try {
    $pdo->exec('UPDATE accounts SET balance = balance - 100 WHERE id = 1');
    $pdo->exec('UPDATE accounts SET balance = balance + 100 WHERE id = 2');
    $pdo->commit();
} catch (PDOException $e) {
    $pdo->rollBack();
    echo 'Ошибка транзакции: ' . $e->getMessage();
}
(нет вывода при успехе, или сообщение об ошибке)

Транзакции обеспечивают атомарность операций. Если один из запросов завершается неудачей, все изменения откатываются.

Выборка в объекты с помощью PDO

Пример
class User {
    public $id;
    public $name;
    public $email;
}
$stmt = $pdo->query('SELECT id, name, email FROM users');
$users = $stmt->fetchAll(PDO::FETCH_CLASS, 'User');
foreach ($users as $user) {
    echo $user->name . '<br>';
}
Иван Петров
Мария Смирнова
...

Режим выборки FETCH_CLASS автоматически создаёт экземпляры указанного класса и заполняет свойства.

Использование подготовленных запросов в mysqli

Пример
$stmt = $mysqli->prepare('SELECT * FROM products WHERE price > ? AND category = ?');
$stmt->bind_param('ds', $minPrice, $category);
$minPrice = 10.50;
$category = 'electronics';
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
    echo $row['name'] . ' - ' . $row['price'] . '<br>';
}
Ноутбук - 55000
Мышь - 15.99
...

Метод bind_param принимает строку с типами параметров (d - double, s - string). Важно соблюдать последовательность.

Обработка ошибок в mysqli через исключения

Пример
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
try {
    $mysqli = new mysqli('localhost', 'root', '', 'test');
    $result = $mysqli->query('SELECT * FROM non_existent_table');
} catch (mysqli_sql_exception $e) {
    echo 'Ошибка MySQL: ' . $e->getMessage();
}
Ошибка MySQL: Table 'test.non_existent_table' doesn't exist

Включение строгого отчёта заставляет mysqli выбрасывать исключения, что упрощает обработку ошибок.

Уроки по PHP и MySQL - comments

En
уроки php mysql (php)