SELECT, метод $pdo->query() та fetchAll().INSERT та додавання нового запису.SELECT).Ми навчилися підключатися до БД. Тепер настав час “оживити” наш сайт. Усі повноцінні веб-проєкти (чи то інтернет-магазин, чи блог, чи наш “Менеджер завдань”) базуються на чотирьох китах: ви можете Create (Створити) ресурс, Read (Прочитати) його, Update (Оновити) та Delete (Видалити) його. У цій лекції ми навчимося формувати SQL-запити через PHP для виконання перших двох літер: C (Створення) та R (Читання).
Майже кожен функціонал на сайті так чи інакше зводиться до CRUD:
INSERT.SELECT.UPDATE.DELETE.SELECTМова SQL створена так, щоб нагадувати звичайну англійську.
Щоб прочитати інформацію, використовується команда SELECT (“обрати”).
SELECT title, priority FROM tasks — Дістати лише дві колонки з таблиці tasks.SELECT * FROM tasks — Зірочка означає “дістати абсолютно всі стовпці” (ID, назву, опис тощо). Це найпоширеніший спосіб для простих таблиць.query()Щоб виконати цей рядок за допомогою нашого “мосту” (змінної $pdo), ми використовуємо метод query(). Цей метод найкраще підходить для статичних, безпечних запитів, де ми просто кажемо базі “Дай усе” і не підмішуємо жодного вводу від користувача (такого як пошукові фрази).
<?php
require_once 'db.php'; // Інтегрували підключення (отримали об'єкт $pdo)
// 1. Формуємо рядок SQL-запиту
$sql = 'SELECT * FROM tasks ORDER BY id DESC'; // ORDER BY DESC - найсвіжіші зверху
// 2. Відправляємо запит до БД
$stmt = $pdo->query($sql);
// $stmt (Statement) - це ще НЕ масив рядків. Це об'єкт "результату",
// який тримає в собі відповідь сервера бази даних.
?>
fetchAll()Щоб перетворити технічний $stmt на звичайний PHP-масив, ми викликаємо метод fetchAll(). Завжди передавайте йому параметр конфігурації PDO::FETCH_ASSOC, щоб повернути чистий асоціативний масив за ключами колонок і зекономити оперативну пам’ять сервера:
<?php
// 3. Завантажуємо всі рядки у змінну $tasks
$tasks = $stmt->fetchAll(PDO::FETCH_ASSOC);
/* Тепер $tasks це звичний багатовимірний масив:
[
[ "id" => "2", "title" => "Зробити ДЗ", "status" => "0" ],
[ "id" => "1", "title" => "Купити Хліб", "status" => "1" ]
]
*/
?>
Тепер, коли ми маємо PHP-масив у змінній $tasks, нам потрібно його лише перебрати стандартним циклом foreach всередині нашого HTML-шаблону index.php.
Важливо: щоб хакер не зміг заразити наш сайт через введені раніше JavaScript-теги у базу, будь-який вивід текстових даних з БД має “очищуватися” функцією htmlspecialchars().
<!DOCTYPE html>
<html>
<body>
<h1>Список усіх завдань</h1>
<ul>
<?php foreach ($tasks as $task): ?>
<li>
<strong><?= htmlspecialchars($task['title']) ?></strong>
<small>(Статус: <?= $task['status'] ?>)</small>
</li>
<?php endforeach; ?>
</ul>
</body>
</html>
INSERTТепер реалізуємо можливість додати нове завдання (літера C - Create).
За це в SQL відповідає оператор INSERT INTO.
Синтаксис: INSERT INTO таблиця (стовпець1, стовпець2) VALUES ('значення1', 'значення2').
Зверніть увагу: ми ніколи не вставляємо стовпець id, тому що він має прапорець Auto_Increment у нашій базі та створюється автоматично.
Уявімо скрипт add_task.php, який приймає Дані з POST-форми:
<?php
require_once 'db.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$newTaskTitle = $_POST['title']; // 'Прибрати в кімнаті'
// БАЗОВИЙ ПРИКЛАД: ми "вклеюємо" змінну прямісінько в рядок запиту.
// УВАГА! Цей метод ($pdo->query з конкатенацією) є вкрай небезпечним
// для справжніх проєктів (через SQL-ін'єкції!). Ми використаємо його тут
// виключно для початкового розуміння логіки роботи SQL. На Лекції 14
// ми зробимо цей код безпечним і професійним!
$sql = "INSERT INTO tasks (title, status) VALUES ('$newTaskTitle', 0)";
// Відправляємо сформований текст до MySQL
$pdo->query($sql);
// Перенаправляємо (Redirect) назад на головну сторінку, щоб уникнути
// повторної відправки форми, якщо юзер натисне F5 (Оновлення сторінки)
header("Location: index.php");
exit;
}
?>
Створивши HTML форму введення і направивши її action="add_task.php" method="POST", ви тепер маєте повноцінний цикл створення та прочитання (Create + Read).
SELECT виконується методом $pdo->query() і повертає об’єкт-стейтмент, масив з якого витягується через fetchAll(PDO::FETCH_ASSOC).foreach всередині HTML.INSERT INTO. Стовпці з властивістю Auto_Increment вписувати під час вставки не потрібно.header('Location: ...'), для повернення на сторінку-список та захисту від дублювання дії.SELECT: https://www.w3schools.com/sql/sql_select.aspINSERT: https://www.w3schools.com/sql/sql_insert.aspfetchAll: https://www.php.net/manual/ru/pdostatement.fetchall.phpCRUD. З якими основними SQL-операторами ці літери співвідносяться?$stmt->fetchAll(PDO::FETCH_ASSOC) віддає нам дані з таблиці. Чому використання прапорця FETCH_ASSOC є кращою практикою, аніж його відсутність?<ul> списку, а робити $pdo->query в самому верху PHP-файлу (чи в окремому контролері), і лише нижче в HTML ітерувати його через foreach?INSERT INTO users (name, email) VALUES ... ми пропустили стовпець id. Чому база не видасть помилки і звідки вона знатиме, який ID присвоїти новоствореному користувачу?header("Location: index.php"); exit;. Що станеться, якщо після додавання товару в кошик через POST, система просто “намалює” сторінку-успіх без редиректа, а користувач випадково натисне F5 (Refresh) у своєму браузері?