Как работать с 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->query($sql);
if ($result) {
while ($row = $result->fetch_assoc()) {
echo "ID: {$row['id']} | Пользователь: {$row['username']} | Email: {$row['email']}<br>";
}
$result->free();
}
$mysqli->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->query($sql) === TRUE) {
echo "Запись успешно обновлена!";
} else {
echo "Ошибка: " . $mysqli->error;
}
$mysqli->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->query($sql) === TRUE) {
echo "Запись успешно удалена!";
} else {
echo "Ошибка: " . $mysqli->error;
}
$mysqli->close();
Подготовленные выражения и защита от SQL-инъекций
Использовать обычные строковые запросы (mysqli_query) небезопасно, если данные поступают от пользователя. Например:
$sql = "SELECT * FROM users WHERE username='$user_input'";
Если $user_input содержит вредоносный код, это приведет к SQL-инъекции. Для решения этой проблемы можно использовать подготовленные выражения (Prepared Statements).
Принцип работы:
- SQL-запрос создается с плейсхолдерами (?).
- Параметры привязываются к плейсхолдерам.
- Сервер MySQL выполняет запрос безопасно, без возможности внедрения произвольного кода.
Пример INSERT (объектно-ориентированный стиль):
$mysqli = new mysqli("localhost", "user", "password", "test_db");
$stmt = $mysqli->prepare("INSERT INTO users (username, email) VALUES (?, ?)");
$stmt->bind_param("ss", $username, $email);
$username = "Anna";
$email = "anna@example.com";
$stmt->execute();
echo "Запись успешно добавлена с подготовленным выражением!";
$stmt->close();
$mysqli->close();
Пример SELECT с параметром:
$mysqli = new mysqli("localhost", "user", "password", "test_db");
$stmt = $mysqli->prepare("SELECT id, username, email FROM users WHERE username = ?");
$stmt->bind_param("s", $username);
$username = "Anna";
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
echo "ID: {$row['id']} | Пользователь: {$row['username']} | Email: {$row['email']}<br>";
}
$stmt->close();
$mysqli->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->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->free();
}
$mysqli->close();
Пример использования mysqli_fetch_row():
$mysqli = new mysqli("localhost", "user", "password", "test_db");
$result = $mysqli->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->free();
}
$mysqli->close();
Пример использования mysqli_fetch_array()
$mysqli = new mysqli("localhost", "user", "password", "test_db");
$result = $mysqli->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->free();
}
$mysqli->close();
Пример использования mysqli_fetch_object():
$mysqli = new mysqli("localhost", "user", "password", "test_db");
$result = $mysqli->query("SELECT id, username, email FROM users");
if ($result) {
while ($user = mysqli_fetch_object($result)) {
echo "ID: {$user->id} | Пользователь: {$user->username} | Email: {$user->email}<br>";
}
$result->free();
}
$mysqli->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->query($sql) === TRUE) {
$last_id = $mysqli->insert_id;
echo "Новая запись добавлена! ID: $last_id";
} else {
echo "Ошибка: " . $mysqli->error;
}
$mysqli->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->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Подключение к базе данных установлено!";
} catch (PDOException $e) {
die("Ошибка подключения: " . $e->getMessage());
}
Выборка данных
PDO позволяет получать результаты в разных форматах:
- PDO::FETCH_ASSOC — ассоциативный массив (ключи = имена колонок);
- PDO::FETCH_NUM — нумерованный массив (0,1,2…);
- PDO::FETCH_BOTH — одновременно ассоциативный и нумерованный массив;
- PDO::FETCH_OBJ — объект с доступом к колонкам через свойства.
Пример выборки:
$stmt = $pdo->query("SELECT id, username, email FROM users");
// Ассоциативный массив
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo "ID: {$row['id']} | Пользователь: {$row['username']} | Email: {$row['email']}<br>";
}
// Или объект
$stmt = $pdo->query("SELECT id, username, email FROM users");
while ($user = $stmt->fetch(PDO::FETCH_OBJ)) {
echo "ID: {$user->id} | Пользователь: {$user->username} | Email: {$user->email}<br>";
}
Вставка данных (INSERT)
Подготовленное выражение:
$stmt = $pdo->prepare("INSERT INTO users (username, email) VALUES (:username, :email)");
$stmt->execute([
':username' => 'Ivan',
':email' => 'ivan@example.com'
]);
echo "Новая запись успешно добавлена! ID: " . $pdo->lastInsertId();
- :username и :email — именованные параметры;
- execute() безопасно подставляет значения, предотвращая SQL-инъекции;
- lastInsertId() возвращает ID последней вставленной записи.
Редактирование данных (UPDATE)
$stmt = $pdo->prepare("UPDATE users SET email = :email WHERE username = :username");
$stmt->execute([
':email' => 'ivan_new@example.com',
':username' => 'Ivan'
]);
echo "Запись успешно обновлена! Обновлено строк: " . $stmt->rowCount();
- rowCount() возвращает количество измененных строк.
Использование подготовленных выражений гарантирует безопасность.
Удаление данных (DELETE)
$stmt = $pdo->prepare("DELETE FROM users WHERE username = :username");
$stmt->execute([
':username' => 'Ivan'
]);
echo "Запись удалена! Удалено строк: " . $stmt->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-приложений, позволяя эффективно работать с базой данных, минимизировать ошибки и предотвращать потенциальные уязвимости.