Практическое руководство по 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 выбрасывать исключения, что упрощает обработку ошибок.