Как работать с MySQL в PHP - Академия Selectel

Как работать с MySQL в PHP

Рассмотрим, как организовать взаимодействие PHP-приложений с MySQL: подключаться к базе, выполнять запросы, обрабатывать результаты и безопасно работать с данными. Все на практических примерах.

Работа с базами данных — один из ключевых аспектов разработки веб-приложений. Большинство современных сайтов и сервисов используют их для хранения и обработки информации: от простых блогов до сложных корпоративных систем. В связке с PHP наиболее часто применяется MySQL — популярная реляционная система управления базами данных, отличающаяся скоростью, надежностью и широкой поддержкой.

Расширение mysqli 

Mysqli (MySQL Improved) — это расширение для PHP, предназначенное для установления связи с базами данных MySQL. Оно пришло на смену устаревшему расширению mysql, которое было удалено в PHP 7. В отличие от своего предшественника, mysqli предоставляет более современный и функциональный интерфейс для взаимодействия с сервером MySQL. Основные преимущества mysqli:

  • Поддержка MySQL 4.1+. Расширение mysql не умело работать с новыми возможностями СУБД. А mysqli поддерживает современные функции MySQL, включая транзакции, множественные соединения и подготовленные выражения.
  • Подготовленные выражения (Prepared Statements). В mysql запросы формировались обычной строкой, что повышало риск SQL-инъекций. В mysqli можно использовать подготовленные выражения с привязкой параметров, что делает запросы более безопасными и надежными.
  • Два стиля работы. Mysql позволял работать только в процедурном стиле, а mysqli поддерживает как процедурный, так и объектно-ориентированный подход.
  • Поддержка транзакций и сохраненных процедур в mysql не было, в то время как mysqli позволяет управлять транзакциями (BEGIN, COMMIT, ROLLBACK) и работать с процедурами на стороне сервера.
  • Multi Query. В mysql выполнение нескольких запросов за один вызов не поддерживалось. В mysqli можно выполнять пакетные запросы и обрабатывать несколько наборов результатов.
  • Асинхронные запросы. В mysql запросы всегда выполнялись синхронно. В mysqli доступна асинхронная работа, что полезно для высоконагруженных систем.
  • Совместимость и будущее. Mysql устарело и полностью исключено из PHP, а mysqli развивается и остается официально поддерживаемым инструментом для взаимодействия с MySQL.

Начало работы с MySQL. Подключение к серверу СУБД через mysqli connect

Чтобы начать работать с базой данных MySQL через расширение mysqli, необходимо установить соединение с сервером СУБД. В процедурном стиле для этого используется функция mysqli_connect():


      mysqli_connect(host, username, password, database, port, socket);

Здесь:

  • host — адрес сервера базы данных (например, localhost или IP-адрес);
  • username — имя пользователя MySQL;
  • password — пароль для подключения;
  • database (необязательно) — имя базы данных, к которой нужно подключиться;
  • port (необязательно) — номер порта (по умолчанию 3306);
  • socket (необязательно) — путь к сокету, если используется локальное соединение.

Пример подключения и проверки соединения:


      
$connection = mysqli_connect("localhost", "user", "password", "test_db");

if (!$connection) {
    die("Ошибка подключения: " . mysqli_connect_error());
}

echo "Успешное подключение к базе данных!";
mysqli_close($connection);

В случае ошибки функция mysqli_connect_error() возвращает текстовое описание проблемы, например:


      Ошибка подключения: Access denied for user 'user'@'localhost' (using password: YES)

Также существует объектно-ориентированный способ подключения:


      $mysqli = new mysqli("localhost", "user", "password", "test_db");

if ($mysqli->connect_errno) {
    echo "Ошибка подключения: " . $mysqli->connect_error;
    exit();
}

echo "Соединение установлено!";
$mysqli->close();

Использование объектного подхода чаще считается более современным и удобным, так как позволяет работать с методами и свойствами объекта.

Установка кодировки UTF-8

После подключения к серверу MySQL важно сразу задать корректную кодировку соединения. Это необходимо для того, чтобы данные сохранялись и отображались правильно.

По умолчанию сервер может использовать другую кодировку (например, latin1), что приводит к искажению символов. Чтобы избежать проблем, рекомендуется сразу устанавливать UTF-8 или его современную версию utf8mb4 (поддерживает полный набор Unicode, включая эмодзи).

Установка кодировки в процедурном стиле:


      $connection = mysqli_connect("localhost", "user", "password", "test_db");

if (!$connection) {
    die("Ошибка подключения: " . mysqli_connect_error());
}

// Устанавливаем кодировку соединения
mysqli_set_charset($connection, "utf8mb4");

echo "Кодировка успешно установлена!";
mysqli_close($connection);

Установка кодировки в объектно-ориентированном стиле:


      $mysqli = new mysqli("localhost", "user", "password", "test_db");

if ($mysqli->connect_errno) {
    die("Ошибка подключения: " . $mysqli->connect_error);
}

// Устанавливаем кодировку соединения
$mysqli->set_charset("utf8mb4");

echo "Кодировка успешно установлена!";
$mysqli->close();

Почему лучше использовать utf8mb4, а не utf8:

  • utf8 в MySQL хранит символы максимум в 3 байтах, что не покрывает весь стандарт Unicode;
  • utf8mb4 поддерживает четырехбайтные символы, включая редкие и современные.
  • Начиная с MySQL 5.5.3, рекомендуется всегда использовать именно utf8mb4.

Создание БД и таблицы

После успешного подключения к серверу MySQL через mysqli можно создавать базы данных и таблицы. Это выполняется с помощью SQL-запросов, отправляемых через функцию mysqli_query() (процедурный стиль) или метод query() (объектно-ориентированный стиль).

Создание базы данных

Пример на процедурном стиле:


      $connection = mysqli_connect("localhost", "user", "password");

if (!$connection) {
    die("Ошибка подключения: " . mysqli_connect_error());
}

// Создаём базу данных
$sql = "CREATE DATABASE test_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci";

if (mysqli_query($connection, $sql)) {
    echo "База данных успешно создана!";
} else {
    echo "Ошибка создания БД: " . mysqli_error($connection);
}

mysqli_close($connection);
?>

Пример на объектно-ориентированном стиле:


      connect_errno) {
    die("Ошибка подключения: " . $mysqli->connect_error);
}

$sql = "CREATE DATABASE test_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci";

if ($mysqli->query($sql) === TRUE) {
    echo "База данных успешно создана!";
} else {
    echo "Ошибка создания БД: " . $mysqli->error;
}

$mysqli->close();

Создание таблицы

После создания базы данных нужно выбрать ее (USE test_db;) или подключиться заново, указав имя БД в параметрах. Далее можно создать таблицу:


      $connection = mysqli_connect("localhost", "user", "password", "test_db");

if (!$connection) {
    die("Ошибка подключения: " . mysqli_connect_error());
}

$sql = "CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL UNIQUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB";

if (mysqli_query($connection, $sql)) {
    echo "Таблица 'users' успешно создана!";
} else {
    echo "Ошибка создания таблицы: " . mysqli_error($connection);
}

mysqli_close($connection);

Выполнение SQL-запросов

После установления соединения с сервером MySQL основная работа сводится к выполнению SQL-запросов. С их помощью можно:

  • добавлять новые данные в таблицы,
  • получать сохраненную информацию,
  • изменять существующие записи,
  • удалять ненужные данные.

Расширение mysqli предоставляет для этого удобные функции (mysqli_query()) и методы ($mysqli->query()), которые позволяют работать как в процедурном, так и в объектно-ориентированном стиле.

Такие операции обычно объединяют в понятие CRUD (от английского Create, Read, Update, Delete) — это полный набор базовых действий с данными в базе.

Мы рассмотрим каждое из них:

  • добавление данных (CREATE) — вставка новых записей в таблицы;
  • чтение данных (READ) — выборка информации с помощью SELECT;
  • изменение данных (UPDATE) — обновление существующих записей;
  • удаление данных (DELETE) — удаление ненужных записей.

Каждая из этих операций будет показана на примере работы с таблицей users в двух стилях: процедурном и объектно-ориентированном.

Добавление данных (CREATE)

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

Процедурный стиль:


      $connection = mysqli_connect("localhost", "user", "password", "test_db");

$sql = "INSERT INTO users (username, email) VALUES ('Alex', 'alex@example.com')";

if (mysqli_query($connection, $sql)) {
    echo "Новая запись успешно добавлена!";
} else {
    echo "Ошибка: " . mysqli_error($connection);
}

mysqli_close($connection);
?>

Объектно-ориентированный стиль:


      query($sql) === TRUE) {
    echo "Новая запись успешно добавлена!";
} else {
    echo "Ошибка: " . $mysqli->error;
}

$mysqli->close();

Чтение данных (READ)

Операция READ позволяет получать информацию из базы данных с помощью запросов SELECT. Она используется для отображения данных пользователю, анализа или обработки внутри приложения.

Процедурный стиль:


      $connection = mysqli_connect("localhost", "user", "password", "test_db");

$sql = "SELECT id, username, email FROM users";
$result = mysqli_query($connection, $sql);

if ($result) {
    while ($row = mysqli_fetch_assoc($result)) {
        echo "ID: {$row['id']} | Пользователь: {$row['username']} | Email: {$row['email']}<br>";
    }
    mysqli_free_result($result);
}

mysqli_close($connection);

Объектно-ориентированный стиль:


      $mysqli = new mysqli("localhost", "user", "password", "test_db");

$sql = "SELECT id, username, email FROM users";
$result = $mysqli-&gt;query($sql);

if ($result) {
    while ($row = $result-&gt;fetch_assoc()) {
        echo "ID: {$row['id']} | Пользователь: {$row['username']} | Email: {$row['email']}<br>";
    }
    $result-&gt;free();
}

$mysqli-&gt;close();

Изменение данных (UPDATE)

Операция UPDATE используется для изменения существующих записей в базе данных. Она необходима, когда нужно нужно исправить или обновить данные, например, изменить адрес электронной почты пользователя или статус заказа.

Процедурный стиль:


      $connection = mysqli_connect("localhost", "user", "password", "test_db");

$sql = "UPDATE users SET email='alex_new@example.com' WHERE username='Alex'";

if (mysqli_query($connection, $sql)) {
    echo "Запись успешно обновлена!";
} else {
    echo "Ошибка: " . mysqli_error($connection);
}

mysqli_close($connection);

Объектно-ориентированный стиль:


      $mysqli = new mysqli("localhost", "user", "password", "test_db");

$sql = "UPDATE users SET email='olga_new@example.com' WHERE username='Olga'";

if ($mysqli-&gt;query($sql) === TRUE) {
    echo "Запись успешно обновлена!";
} else {
    echo "Ошибка: " . $mysqli-&gt;error;
}

$mysqli-&gt;close();

Удаление данных (DELETE)

Операция DELETE используется для удаления записей из таблицы. Она помогает освобождать место в базе данных и удалять устаревшие или ненужные данные.

Процедурный стиль:


      $connection = mysqli_connect("localhost", "user", "password", "test_db");

$sql = "DELETE FROM users WHERE username='Alex'";

if (mysqli_query($connection, $sql)) {
    echo "Запись успешно удалена!";
} else {
    echo "Ошибка: " . mysqli_error($connection);
}

mysqli_close($connection);

Объектно-ориентированный стиль:


      $mysqli = new mysqli("localhost", "user", "password", "test_db");

$sql = "DELETE FROM users WHERE username='Olga'";

if ($mysqli-&gt;query($sql) === TRUE) {
    echo "Запись успешно удалена!";
} else {
    echo "Ошибка: " . $mysqli-&gt;error;
}

$mysqli-&gt;close();

Подготовленные выражения и защита от SQL-инъекций

Использовать обычные строковые запросы (mysqli_query) небезопасно, если данные поступают от пользователя. Например:


      $sql = "SELECT * FROM users WHERE username='$user_input'";

Если $user_input содержит вредоносный код, это приведет к SQL-инъекции. Для решения этой проблемы можно использовать подготовленные выражения (Prepared Statements).

Принцип работы:

  1. SQL-запрос создается с плейсхолдерами (?).
  2. Параметры привязываются к плейсхолдерам.
  3. Сервер MySQL выполняет запрос безопасно, без возможности внедрения произвольного кода.

Пример INSERT (объектно-ориентированный стиль):


      $mysqli = new mysqli("localhost", "user", "password", "test_db");

$stmt = $mysqli-&gt;prepare("INSERT INTO users (username, email) VALUES (?, ?)");
$stmt-&gt;bind_param("ss", $username, $email);

$username = "Anna";
$email = "anna@example.com";
$stmt-&gt;execute();

echo "Запись успешно добавлена с подготовленным выражением!";

$stmt-&gt;close();
$mysqli-&gt;close();

Пример SELECT с параметром:


      $mysqli = new mysqli("localhost", "user", "password", "test_db");

$stmt = $mysqli-&gt;prepare("SELECT id, username, email FROM users WHERE username = ?");
$stmt-&gt;bind_param("s", $username);

$username = "Anna";
$stmt-&gt;execute();

$result = $stmt-&gt;get_result();
while ($row = $result-&gt;fetch_assoc()) {
    echo "ID: {$row['id']} | Пользователь: {$row['username']} | Email: {$row['email']}<br>";
}

$stmt-&gt;close();
$mysqli-&gt;close();

Преимущества подготовленных выражений:

  • защита от SQL-инъекций,
  • возможность многократного выполнения одного запроса с разными параметрами,
  • упрощение обработки данных пользователя.

Просмотр таблиц

После выполнения SQL-запроса SELECT результат хранится в объекте или ресурсе, который нужно обработать, чтобы получить сами строки. Расширение mysqli предоставляет несколько функций для этого:

  • mysqli_fetch_assoc() — возвращает строку в виде ассоциативного массива (ключи = имена колонок);
  • mysqli_fetch_row() — возвращает строку в виде нумерованного массива (0,1,2…);
  • mysqli_fetch_array() — возвращает строку одновременно в виде ассоциативного и нумерованного массива;
  • mysqli_fetch_object() — возвращает строку как объект, где колонки доступны через свойства.

Пример использования mysqli_fetch_assoc():


      $mysqli = new mysqli("localhost", "user", "password", "test_db");

$result = $mysqli-&gt;query("SELECT id, username, email FROM users");

if ($result) {
    while ($row = mysqli_fetch_assoc($result)) {
        echo "ID: {$row['id']} | Пользователь: {$row['username']} | Email: {$row['email']}<br>";
    }
    $result-&gt;free();
}

$mysqli-&gt;close();

Пример использования mysqli_fetch_row():


      $mysqli = new mysqli("localhost", "user", "password", "test_db");

$result = $mysqli-&gt;query("SELECT id, username, email FROM users");

if ($result) {
    while ($row = mysqli_fetch_row($result)) {
        echo "ID: $row[0] | Пользователь: $row[1] | Email: $row[2]<br>";
    }
    $result-&gt;free();
}

$mysqli-&gt;close();

Пример использования mysqli_fetch_array()


      $mysqli = new mysqli("localhost", "user", "password", "test_db");

$result = $mysqli-&gt;query("SELECT id, username, email FROM users");

if ($result) {
    while ($row = mysqli_fetch_array($result, MYSQLI_BOTH)) {
        echo "ID: {$row['id']} | Пользователь: {$row['username']} | Email: {$row[2]}<br>";
    }
    $result-&gt;free();
}

$mysqli-&gt;close();

Пример использования mysqli_fetch_object():


      $mysqli = new mysqli("localhost", "user", "password", "test_db");

$result = $mysqli-&gt;query("SELECT id, username, email FROM users");

if ($result) {
    while ($user = mysqli_fetch_object($result)) {
        echo "ID: {$user-&gt;id} | Пользователь: {$user-&gt;username} | Email: {$user-&gt;email}<br>";
    }
    $result-&gt;free();
}

$mysqli-&gt;close();

Советы при просмотре таблиц:

  • при работе с большими таблицами используйте LIMIT и условия WHERE для ограничения объема данных;
  • после обработки результата всегда вызывайте free(), чтобы освободить память;
  • выбирайте формат выборки (assoc, row, array, object) в зависимости от удобства работы с данными в вашем коде.

Получение идентификатора записи (insert id)

При добавлении новой записи в таблицу с полем AUTO_INCREMENT часто требуется узнать, какой ID был присвоен этой записи. В расширении mysqli для этого используются свойство insert_id (объектно-ориентированный стиль) или функция mysqli_insert_id() (процедурный стиль).

Пример в процедурном стиле:


      $connection = mysqli_connect("localhost", "user", "password", "test_db");

$sql = "INSERT INTO users (username, email) VALUES ('Dmitry', 'dmitry@example.com')";

if (mysqli_query($connection, $sql)) {
    $last_id = mysqli_insert_id($connection);
    echo "Новая запись добавлена! ID: $last_id";
} else {
    echo "Ошибка: " . mysqli_error($connection);
}

mysqli_close($connection);

Пример в объектно-ориентированном стиле:


      $mysqli = new mysqli("localhost", "user", "password", "test_db");

$sql = "INSERT INTO users (username, email) VALUES ('Elena', 'elena@example.com')";

if ($mysqli-&gt;query($sql) === TRUE) {
    $last_id = $mysqli-&gt;insert_id;
    echo "Новая запись добавлена! ID: $last_id";
} else {
    echo "Ошибка: " . $mysqli-&gt;error;
}

$mysqli-&gt;close();

Что важно знать

  • insert_id работает только для таблиц с полем AUTO_INCREMENT;
  • если запрос не вставил запись, значение insert_id будет 0;
  • полученный ID удобно использовать для создания связанных записей в других таблицах (например, добавление заказа с привязкой к пользователю).

PDO для подключения к базе данных mysql

PDO (PHP Data Objects) — это расширение PHP для работы с различными СУБД, в том числе MySQL. Оно обеспечивает единый интерфейс для подключения, выполнения запросов и обработки результатов. Основные преимущества PDO:

  • поддержка подготовленных выражений, что защищает от SQL-инъекций;
  • возможность работы с разными СУБД без изменения основного кода;
  • удобная работа с выборкой данных (PDO::FETCH_ASSOC, PDO::FETCH_OBJ и другие).

Подключение к базе данных

Прежде чем работать с MySQL через PDO, необходимо установить соединение с сервером базы данных. Для этого используется объект PDO, которому передается информация о сервере, имени базы данных, имени пользователя и пароле. Подключение можно обернуть в блок try-catch, чтобы корректно обрабатывать ошибки и сразу получать уведомления о проблемах с соединением.


      $dsn = "mysql:host=localhost;dbname=test_db;charset=utf8mb4";
$user = "user";
$password = "password";

try {
    $pdo = new PDO($dsn, $user, $password);
    // Включаем исключения при ошибках
    $pdo-&gt;setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    echo "Подключение к базе данных установлено!";
} catch (PDOException $e) {
    die("Ошибка подключения: " . $e-&gt;getMessage());
}

Выборка данных

PDO позволяет получать результаты в разных форматах:

  • PDO::FETCH_ASSOC — ассоциативный массив (ключи = имена колонок);
  • PDO::FETCH_NUM — нумерованный массив (0,1,2…);
  • PDO::FETCH_BOTH — одновременно ассоциативный и нумерованный массив;
  • PDO::FETCH_OBJ — объект с доступом к колонкам через свойства.

Пример выборки:


      $stmt = $pdo-&gt;query("SELECT id, username, email FROM users");

// Ассоциативный массив
while ($row = $stmt-&gt;fetch(PDO::FETCH_ASSOC)) {
    echo "ID: {$row['id']} | Пользователь: {$row['username']} | Email: {$row['email']}<br>";
}

// Или объект
$stmt = $pdo-&gt;query("SELECT id, username, email FROM users");
while ($user = $stmt-&gt;fetch(PDO::FETCH_OBJ)) {
    echo "ID: {$user-&gt;id} | Пользователь: {$user-&gt;username} | Email: {$user-&gt;email}<br>";
}

Вставка данных (INSERT)

Подготовленное выражение:


      $stmt = $pdo-&gt;prepare("INSERT INTO users (username, email) VALUES (:username, :email)");

$stmt-&gt;execute([
    ':username' =&gt; 'Ivan',
    ':email' =&gt; 'ivan@example.com'
]);

echo "Новая запись успешно добавлена! ID: " . $pdo-&gt;lastInsertId();
  • :username и :email — именованные параметры;
  • execute() безопасно подставляет значения, предотвращая SQL-инъекции;
  • lastInsertId() возвращает ID последней вставленной записи.

Редактирование данных (UPDATE)


      $stmt = $pdo-&gt;prepare("UPDATE users SET email = :email WHERE username = :username");

$stmt-&gt;execute([
    ':email' =&gt; 'ivan_new@example.com',
    ':username' =&gt; 'Ivan'
]);

echo "Запись успешно обновлена! Обновлено строк: " . $stmt-&gt;rowCount();
  • rowCount() возвращает количество измененных строк.

Использование подготовленных выражений гарантирует безопасность.

Удаление данных (DELETE)


      $stmt = $pdo-&gt;prepare("DELETE FROM users WHERE username = :username");

$stmt-&gt;execute([
    ':username' =&gt; 'Ivan'
]);

echo "Запись удалена! Удалено строк: " . $stmt-&gt;rowCount();
  • условие WHERE обязательно, чтобы не удалить все записи;
  • rowCount() показывает, сколько строк удалено.

PDO позволяет безопасно и удобно работать с MySQL: подключаться к базе, выполнять выборку, вставку, редактирование и удаление данных, а также контролировать результаты операций.

MySQL на инфраструктуре Selectel

Вы можете использовать облачные managed-решения Selectel для размещения баз данных. DBaaS — это облачная услуга, которая позволяет использовать базы данных без необходимости самостоятельного развертывания и управления серверами. Все уже готово для вашей работы.

Selectel предоставляет полностью управляемые инстансы MySQL, PostgreSQL и других СУБД. Это упрощает администрирование и ускоряет запуск проектов.

Заключение

Работа с базой данных MySQL — неотъемлемая частью разработки современных веб-приложений на PHP. В статье мы рассмотрели основные инструменты и подходы для эффективного взаимодействия с СУБД — вспомним основные моменты.

Расширение mysqli позволяет подключаться к серверу MySQL, создавать базы данных и таблицы, выполнять все CRUD-операции (добавление, чтение, редактирование, удаление), использовать подготовленные выражения для защиты от SQL-инъекций, управлять кодировкой UTF-8 и получать идентификаторы вставленных записей.

Функции mysqli_fetch_… дают гибкость при выборке данных в виде ассоциативных массивов, нумерованных массивов или объектов, что упрощает работу с результатами запросов.

Класс mysqli_driver позволяет настраивать поведение драйвера, включая режимы отчёта об ошибках, и управлять сессиями соединений.

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

Выбор между mysqli и PDO зависит от потребностей проекта: mysqli удобен для проектов, работающих исключительно с MySQL, тогда как PDO обеспечивает более универсальное и безопасное решение, особенно для кросс-СУБД.

Систематическое использование этих инструментов обеспечивает безопасность, стабильность и масштабируемость PHP-приложений, позволяя эффективно работать с базой данных, минимизировать ошибки и предотвращать потенциальные уязвимости.