setcookie, $_COOKIE).session_start, $_SESSION). Відмінності сесій від Cookies.Як ми неодноразово згадували, протокол HTTP не має пам’яті (Stateless). Коли ви авторизувалися в Instagram, а потім клікнули на чиєсь фото (ініціювавши новий HTTP GET запит) — технічно Instagram вас забув і мав би знову показати форму введення пароля. “Пригадати” вас йому допомагають дві технології: Cookies (печиво) на стороні вашого браузера, та Сесії на стороні їхніх серверів. Це базис будь-якої системи автентифікації, кошика покупок та персоналізованого контенту.
Якщо ми перейдемо зі сторінки page1.php, де ми задали $user = "Олег", на сторінку page2.php, змінна $user виявиться порожньою (Undefined). Як зробити змінну глобальною і “безсмертною” під час подорожі користувача сайтом?
Ми не можемо змусити користувача весь час передавати своє ім’я чи токен доступу в адресній строчці ?user=Олег при кожному кліку — це архітектурно жахливо і небезпечно.
Рішення розділилось на два підходи фронту та бекенду: Cookie та Сесії.
setcookie())Cookie — це крихітний текстовий рядок (макс. 4 КБ), який сервер відправляє в браузер, і браузер слухняно зберігає його десь глибоко на жорсткому диску самого користувача. Головна магія кук в іншому: Браузер зобов’язаний ПРИКРІПЛЯТИ до КОЖНОГО наступного запиту до цього конкретного сайту (на кожну картинку, на кожен клік) всі куки, які він зберіг. “Привіт, Сервер, пам’ятаєш, ти просив запам’ятати це? Ось воно знову”.
Використовується функція setcookie(Ключ, Значення, Термін_Життя).
Критичне правило: Відправляти Cookie можна ТІЛЬКИ ДО ТОГО (найвище у файлі), як ви використали команду echo або навіть вивели <!DOCTYPE html>. Куки — це HTTP-Заголовки. Їх не можна надіслати, якщо тіло HTML вже почало друкуватися. Headers already sent error.
<?php
// Встановлюємо куку 'theme' у значення 'dark'.
// Вона буде "жити" на комп'ютері клієнта 30 днів (в секундах: 60*60*24*30)
$expireDate = time() + (86400 * 30);
setcookie('theme', 'dark', $expireDate, '/');
?>
На всіх інших сторінках сайту, при наступних візитах, PHP автоматично витягне ці куки з запиту браузера й покладе в масив $_COOKIE.
<?php
// Ми вже на іншій сторінці наступного дня
$siteTheme = $_COOKIE['theme'] ?? 'light'; // За замовчуванням 'light'
echo "Ваша улюблена тема: " . $siteTheme;
// ЗНИЩЕННЯ КУКИ:
// Щоб видалити куку (напр. "Вийти"), потрібно встановити їй час життя в МИНУЛЕ:
setcookie('theme', '', time() - 3600, '/');
?>
Головний недолік: Куки легко відкрити й відредагувати через DevTools або розширення. Ніколи не зберігайте в куках ціни товарів у кошику, права адміна (isAdmin=1) або паролі! Користувач їх підробить.
$_SESSION)Сесія працює інакше: вона зберігає всю “конфіденційну” інформацію (наприклад статус адміна чи товари в кошику) на диску самого Сервера в неприступному захищеному місці, і ніхто ззовні не може її підробити.
Як же тоді Сервер розпізнає, яка саме сесія в оперативній пам’яті належить якому браузеру?
Магія: PHP при старті сесії непомітно для вас відсилає одну-єдину технічну Cookie в браузер, яка називається PHPSESSID. В ній лежить довгий рандомний хеш (наприклад abc123xyz). Браузер з кожним кліком надсилає PHPSESSID назад, а PHP дістає потрібний файл на диску з ім’ям abc123xyz і заповнює “оживляє” ваш суперглобальний масив $_SESSION.
Масив $_SESSION порожній і недоступний, поки ви не викличете команду “Дозволяю працювати з сесіями на цій сторінці” — session_start().
Викликати її потрібно найпершим рядком вашого коду index.php (до HTML-тегів, з тієї ж причини, що й з setcookie()).
<?php
session_start();
// Збереження даних у сесію ПРОСТО як у звичайний масив:
$_SESSION['user_name'] = "Іван";
$_SESSION['role'] = "Admin";
$_SESSION['cart_items'] = 5;
// Цей процес зазвичай роблять в обробнику login.php ПІСЛЯ перевірки пароля.
?>
<?php
// ОБОВ'ЯЗКОВО наголошуємо "ми знову хочемо користуватись механізмом"
session_start();
// Перевіряємо, чи був збережений ключ?
if (isset($_SESSION['user_name'])) {
echo "З поверненням у панель, " . $_SESSION['user_name'];
// Іван не зможе через F12 змінити 'role' на щось інше,
// бо ці дані лежать на нашому сервері!
} else {
echo "Ви Гість. Зареєструйтесь.";
}
?>
Об’єднавши знання з минулих уроків (форми) та сьогоднішньої (сесії), ми отримуємо класичний механізм авторизації будь-якого сайту.
login.php)$_POST['email'] та $_POST['password'].if).$_SESSION['is_logged'] = true) і перенаправляємо на профіль.<?php
session_start();
if ($_POST['email'] === 'admin@mail.com' && $_POST['password'] === '123') {
$_SESSION['is_logged'] = true;
$_SESSION['uid'] = 99; // айді користувача
header('Location: profile.php'); // Перенаправлення (Redirect)
exit; // Обов'язково зупиняти код після header(Location)!
} else {
echo "Невірний пароль!";
}
?>
profile.php)У самому верху закритих сторінок, які доступні ТІЛЬКИ зареєстрованим:
<?php
session_start();
if (empty($_SESSION['is_logged'])) { // Або !isset()
die("У вас немає доступу. Будь ласка, залогінтесь.");
// На практиці роблять не die, а: header('Location: login.php'); exit;
}
echo "Вітаємо в секретній зоні (Профілі)!";
?>
logout.php)Для безпечного знищення всіх змінних сесії на сервері, і тим самим розлогінення користувача:
<?php
session_start();
session_unset(); // Очищає пам'ять масиву $_SESSION (всі змінні)
session_destroy(); // Повністю знищує файл сесії на диску сервера
header('Location: index.php'); // Викидаємо назад на головну
exit;
?>
setcookie() або ініціалізувати сесію через session_start() необхідно до будь-якого виводу даних в браузер (до HTML чи echo).$_SESSION) зберігають дані лише на сервері, відповідно єдиним надійним місцем для зберігання фактів типу “Користувач успішно пройшов авторизацію і він Адміністратор”.['is_logged'] = true) в сесію під час перевірки правильного логіна/пароля.Cannot modify header information - headers already sent by...? В який конкретно момент роботи функції session_start() чи setcookie() ця помилка спрацьовує і як її гарантовано уникнути?Cookies чи $_SESSION? Обґрунтуйте ризики обох варіантів.if ($_COOKIE['user_is_super_admin'] === 'yes') { /* видалити всю базу даних */ }. Яка фундаментальна архітектурна вразливість допущена в цій системі перевірки прав адміністратора (Access Control)?$_SESSION['login'] = 'Ivan', і чому сторонній клієнт (навіть досвідчений програміст) принципово не здатен прочитати або змінити цей факт зі свого браузера (через F12)?