03. CRUD-операции и безопасность SQL

Что такое CRUD

CRUD — это аббревиатура четырёх базовых операций с данными:
  • Create — создание (INSERT)
  • Read — чтение (SELECT)
  • Update — обновление (UPDATE)
  • Delete — удаление (DELETE)

Каждое динамическое веб-приложение (форум, блог, магазин) основано именно на этих четырёх действиях.

PHP + MySQL = основа серверного веб-программирования. CRUD — сердце любой CMS.

Подготовка

Перед началом убедитесь, что у вас есть база данных my_app и таблица users, созданная ранее:

CREATE TABLE users (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  email VARCHAR(150) NOT NULL UNIQUE,
  password VARCHAR(255) NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Подключение к базе (db_connect.php):


<?php
$pdo = new PDO('mysql:host=localhost;dbname=my_app;charset=utf8mb4','root','');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
?>

C — Создание записи (INSERT)

Самый надёжный способ — использовать Prepared Statement:

<?php
require 'db_connect.php';

$sql = 'INSERT INTO users (name, email, password) VALUES (?, ?, ?)'; $stmt = $pdo->prepare($sql); $stmt->execute(['Иван', 'ivan@mail.com', md5('12345')]);

echo 'Пользователь добавлен!'; ?>

Почему именно prepare()

Метод prepare() защищает вас от SQL-инъекций, автоматически экранируя опасные символы. Никогда не вставляйте значения прямо в запрос строкой!

Плохо:


$pdo->query("INSERT INTO users (name) VALUES ('$name')");

Правильно:


$stmt = $pdo->prepare('INSERT INTO users (name) VALUES (?)');
$stmt->execute([$name]);

R — Чтение данных (SELECT)

Чтобы получить записи, используйте метод query():

<?php
$stmt = $pdo->query('SELECT * FROM users');
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
  echo $row['id'] . '. ' . $row['name'] . ' — ' . $row['email'] . '<br>';
}
?>

Фильтрация (WHERE)


$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
$stmt->execute(['ivan@mail.com']);
$user = $stmt->fetch();
print_r($user);

Выборка всех строк в массив


$users = $pdo->query('SELECT * FROM users')->fetchAll();
foreach ($users as $u) {
  echo $u['name'].'<br>';
}

U — Обновление данных (UPDATE)


<?php
$stmt = $pdo->prepare('UPDATE users SET name = ? WHERE id = ?');
$stmt->execute(['Алексей', 1]);
echo 'Имя обновлено!';
?>

Несколько обновлений

Можно выполнить несколько операций подряд:

$pdo->prepare('UPDATE users SET email=? WHERE id=?')->execute(['alex@mail.com', 1]);
$pdo->prepare('UPDATE users SET password=? WHERE id=?')->execute([md5('newpass'), 1]);

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


<?php
$stmt = $pdo->prepare('DELETE FROM users WHERE id = ?');
$stmt->execute([2]);
echo 'Пользователь удалён!';
?>

Обработка ошибок

Любая ошибка при работе с БД выбрасывает исключение. Чтобы поймать его:

try {
  $stmt = $pdo->query('SELECT * FROM unknown_table');
} catch (PDOException $e) {
  echo 'Ошибка: ' . $e->getMessage();
}

Безопасность SQL и PHP

SQL-инъекция — это когда злоумышленник вставляет SQL-код в поля ввода, чтобы получить доступ к данным. Например:

Пользователь вводит: ' OR 1=1 --

Если вставить это напрямую:


$sql = "SELECT * FROM users WHERE email='$input'";
Запрос вернёт всех пользователей!

Решение — использовать prepare() и execute().

Дополнительная защита

  • Используйте тип INT для числовых ID и приводите значения:
    (int)$_GET['id']
  • Никогда не показывайте пароли и чувствительные данные в браузере
  • Для паролей используйте password_hash(), а не md5()

Мини-проект: простой список пользователей

Создадим страницу users_list.php, где можно увидеть всех пользователей:

<!doctype html>
<html lang='ru'>
<head>
  <meta charset='utf-8'>
  <title>Список пользователей</title>
</head>
<body>
<h2>Пользователи</h2>
<?php
require 'db_connect.php';
$stmt = $pdo->query('SELECT * FROM users');
while ($row = $stmt->fetch()) {
  echo '<p><b>' . htmlspecialchars($row['name']) . '</b> — ' . htmlspecialchars($row['email']) . '</p>';
}
?>
</body>
</html>

Зачем htmlspecialchars()

Функция htmlspecialchars() защищает от XSS-атак — если в базе окажется скрипт вроде <script>alert(1)</script>, он будет выведен безопасно как текст.

Итоги урока

Вы узнали:
  • Что такое CRUD-операции
  • Как выполнять INSERT, SELECT, UPDATE и DELETE через PDO
  • Как использовать подготовленные выражения для защиты от SQL-инъекций
  • Как обрабатывать ошибки и защищаться от XSS