Почему нельзя использовать устаревшие функции mysql_* в PHP и чем их заменить?
Почему mysql_* — это мёртвая технология?
Вы столкнулись с классической проблемой начинающих: старые учебники и привычка. Функции mysql_* были удалены из PHP начиная с версии 7.0. Это значит, что ваш код просто не будет работать на современных серверах. Но главное — не это, а три фундаментальные проблемы:
- SQL-инъекции — ваш код в вопросе содержит критическую уязвимость. Переменная
$_GET['id']напрямую вставляется в запрос. Злоумышленник может передать?id=1; DROP TABLE users— и вы потеряете данные. - Отсутствие подготовленных выражений — mysql_* не поддерживают параметризованные запросы. Приходится вручную экранировать данные через
mysql_real_escape_string(), но это не панацея (проблемы с кодировками, пропуски). - Смешивание кода и данных — вы пишете запрос как строку с конкатенацией. Это делает код нечитаемым и небезопасным.
Современное решение: PDO (PHP Data Objects)
PDO — это расширение для работы с базами данных, которое поддерживает подготовленные выражения и работает с MySQL, PostgreSQL, SQLite и другими СУБД. Вот как переписать ваш код:
<?php
// 1. Подключение с обработкой ошибок
$dsn = 'mysql:host=localhost;dbname=myblog;charset=utf8mb4';
$user = 'root';
$password = '';
try {
$pdo = new PDO($dsn, $user, $password);
// Включаем режим исключений для ошибок
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die('Ошибка подключения: ' . $e->getMessage());
}
// 2. Подготовленный запрос (безопасно!)
$id = $_GET['id'] ?? 0; // защита от неопределённого ключа
$stmt = $pdo->prepare("SELECT name FROM users WHERE id = :id");
$stmt->execute([':id' => $id]);
// 3. Получение результатов
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo htmlspecialchars($row['name']); // защита от XSS
}
?>
Почему это лучше?
- Безопасность: PDO сам экранирует данные. Даже если передать
1; DROP TABLE— это будет воспринято как строка, а не как часть SQL. - Читаемость: запрос отделён от данных. Места для ошибок меньше.
- Переносимость: достаточно сменить строку подключения DSN — и код работает с другой БД.
- Обработка ошибок: через исключения вы всегда знаете, что пошло не так.
Альтернатива: MySQLi (MySQL improved)
Если вы не хотите переходить на PDO, используйте MySQLi — он тоже поддерживает подготовленные выражения. Но PDO предпочтительнее из-за универсальности.
Итог: забудьте про mysql_* как страшный сон. Учите PDO — это стандарт индустрии. И всегда используйте подготовленные выражения, даже если кажется, что "этот запрос безопасен".
Дополнение: почему не стоит даже начинать с mysql_*
Коллега выше отлично объяснил техническую сторону. Я добавлю важный психологический момент: используя устаревшие функции, вы формируете вредные привычки. Когда вы перейдёте на PDO или MySQLi, вам придётся переучиваться. А это больно и долго.
Ещё один аргумент — сообщество. Если вы выложите код с mysql_* на GitHub или в вопрос на Stack Overflow, вас просто заминусуют. Никто не захочет помогать человеку, который игнорирует современные стандарты.
И последнее: производительность. PDO использует кэширование планов запросов при повторных вызовах подготовленных выражений. Ваш старый код с mysql_query каждый раз парсит запрос заново — это медленнее.
Совет: установите PHP 8.x и включите строгий режим ошибок. Тогда все mysql_* сразу вызовут фатальные ошибки — это лучшая мотивация для перехода на PDO. Удачи в изучении!
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги