nmk

Лабораторна робота №14 (2 години)

Тема: Видалити/Редагувати (Prepared Statements). Реалізація дій “Видалити” (через передачу ID у $_GET) та зміни статусу завдання “Виконано/У процесі”, захист цих SQL-запитів (DELETE / UPDATE) через підготовлені вирази.

Мета: Закріпити навички використання бази даних шляхом реалізації повного циклу операцій (CRUD). Ознайомитися з передачею ідентифікаторів ресурсів через GET-параметри в URL-рядку.

Технологічний стек: SQL (UPDATE, DELETE), PHP ($_GET, PDO::prepare()).

Завдання

  1. Додати HTML-посилання “Видалити” до кожного виведеного в циклі завдання.
  2. Написати скрипт-обробник для безпечного видалення запису з бази даних за його id.
  3. Додати кнопку-посилання “Позначити виконаним”. Зробити обробник оновлення прапорця is_completed у базі.
  4. Застосувати безпечні Prepared Statements для уникнення ін’єкцій через URL.

Хід виконання роботи

Крок 1. Генерація посилань керування

В index.php, під час ітерації масиву $tasks через foreach ($tasks as $task), додайте всередині кожного тегу <li> посилання на видалення і посилання на зміну статусу. Використовуйте ?= $task['id'] ? для підстановки унікального номера:

<a href="delete.php?id=<?= $task['id'] ?>" class="btn">Видалити</a>
<a href="complete.php?id=<?= $task['id'] ?>" class="btn">Змінити статус</a>

Крок 2. Реалізація видалення (DELETE)

Створіть файл delete.php.

  1. Підключіть до нього db.php (require_once 'db.php';).
  2. Перевірте, чи був переданий ідентифікатор в URL: if(isset($_GET['id'])) { $id = $_GET['id']; ... }.
  3. Напишіть підготовлений запит: $stmt = $pdo->prepare('DELETE FROM tasks WHERE id = :id');.
  4. Виконайте його з передачею змінної: $stmt->execute([':id' => $id]);.
  5. Зробіть редірект на головну: header('Location: index.php'); exit;.

Не забувайте про безпеку: якщо зловмисник введе в браузері delete.php?id=1 OR 1=1, підготовлений вираз гарантовано не дасть йому очистити вашу таблицю, а лише попытається знайти id із таким дивним рядком.

Крок 3. Зміна статусу “Виконано” (UPDATE)

Створіть файл complete.php. Процес ідентичний delete.php, але тут ми маємо не видалити рядок, а перемкнути статус булевого поля is_completed на протилежний (або хоча б просто встановити його в 1 / true).

SQL-запит:

UPDATE tasks SET is_completed = 1 WHERE id = :id

Виконайте $stmt->execute([':id' => $id]); і поверніть користувача на index.php. (Додаткове завдання: зробіть так, щоб код спочатку дізнавався статус $task[‘is_completed’], і перемикав його на !$status, роблячи звичайний тогл. Так користувач зможе знімати галочку “Виконано”).

Крок 4. Тестування дій

Відкрийте index.php у браузері. Натисніть на посилання “Видалити” поруч з одним із завдань. Завдання повинно зникнути. Відкрийте phpMyAdmin і переконайтесь, що запису в таблиці більше немає. Натисніть “Змінити статус”, і якщо у вас налаштовані CSS-класи відображення, елемент повинен змінити колір (бо в базі його is_completed став True).

Контрольні запитання

  1. Що роблять оператори SQL DELETE і UPDATE? Чим вони відрізняються?
  2. Яка помилка при написанні запиту UPDATE або DELETE у чистому SQL є найстрашнішою та призводить до модифікації/видалення всієї таблиці відразу? (Підказка: забута конструкція).
  3. Яким чином змінні з адресного рядка .../delete.php?foo=bar&id=5 потрапляють у PHP скрипт і як їх дістати?
  4. Що станеться у файлі delete.php, якщо зловмисник навмисно відвідає адресу delete.php (без передачі ?id=...), і як ви захистили код від збоїв (кидання Notice / Undefined index) в цьому випадку?
  5. Чому метод передачі GET не рекомендується для чутливих операцій зміни стану системи (особливо для видалення контенту) з точки зору REST-архітектури та дій веб-краулерів (напр. пошукових систем Googles/Bing)? Яким методом краще відправляти запит на видалення?

Вимоги до звіту

  1. У файл lab14.md надіслати код файлів обробників: delete.php та complete.php.
  2. Додати скриншот браузера зі списком завдань до видалення і після нього (бажано також скрин з бази даних).
  3. Відправити посилання на коміт у GitHub.
  4. Надати відповіді на контрольні запитання.