nmk

Лекція 6 (2 години). Основи протоколу HTTP та обробка запитів

План лекції

  1. Природа протоколу HTTP: запит-відповідь та відсутність стану (Stateless).
  2. Різниця між методами GET та POST.
  3. Суперглобальні масиви в PHP. Перехоплення параметрів URL через масив $_GET.
  4. URL-кодування (URL-encoding) параметрів.

Перелік умовних скорочень

Вступ

Всесвітня мережа та процес веброзробки тримаються на базі протоколу HTTP. Усі мови програмування — Python, Node.js та PHP — на рівні бекенду просто парсять (аналізують) вхідні текстові запити від браузерів згідно правил цього протоколу, та формують і віддають текстову відповідь. Розуміння відмінностей методів HTTP-запитів і способів передавати параметри в адресному рядку — це “Абетка” для створення динамічних сторінок, таких як результати пошуку або сторінки профілів користувачів. Без них усі сторінки були б завжди однаковими (статичними).


1. Природа протоколу HTTP: Відсутність стану (Stateless)

HTTP (Hypertext Transfer Protocol) — це набір фундаментальних правил, за якими клієнт (як правило, ваш браузер Chrome або Safari) і сервер обмінюються текстовими повідомленнями.

Важлива характеристика HTTP, про яку забувають новачки — він є Stateless (протоколом “без стану”).

Що це означає: Сервер не має “пам’яті”. Після того, як сервер отримав запит від вашого клієнта, побудував сторінку і відправив її назад — він негайно забуває про вас. Кожен наступний клік на сайті по будь-якому посиланню (навіть через 2 секунди) розглядається сервером як 100% новий і незалежний запит від незнайомця.

Тому, якщо ви авторизувалися на сторінці login.php, а потім перейшли на profile.php, сервер вас “вже не знає” ($is_logged=true загубиться). Щоб передавати “стан” (хто ви і що ви уже ввійшли в систему), розробникам доводиться вдаватися до спеціальних інструментів — Cookie та Сесій (про які поговоримо у लेक्चरі 9), або передавати значення щоразу в URL-адресі.

Структура HTTP повідомлення

Невидиме “око” HTTP-запиту від браузера виглядає приблизно так:

GET /articles/category-php HTTP/1.1
Host: www.mysite.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64) Chrome/...
Accept-Language: uk,en-US

Ми бачимо Метод (GET), Шлях (/articles/…) та серію Заголовків (Headers).

2. Різниця між HTTP-методами GET та POST

В протоколі є безліч методів (дієслів) для вказівки “що саме і як має відбутись” із сторінкою, яку запитують. Найбільш вживані: GET і POST.

Метод GET (Отримати / Читати)

Це метод за замовчуванням. Абсолютно кожен раз, коли ви вводите URL в адресний рядок, переходите по посиланню <a> або оновлюєте сторінку по F5 — браузер робить GET-запит.

  1. Призначення: Тільки для читання, не повинен змінювати дані на сервері (напр., не повинен видаляти файл чи створювати товар).
  2. Передача даних: Всі передані користувачем параметри прикріплюються відкрито і прозоро прямо в кінець URL-адреси браузера після знаку питання ?.
  3. Обмеження: В URL не можна вставити картину або багато тексту (максимум кілька кілобайт).
  4. Кешування: GET-запити зберігаються в історії браузера і їх можна легко додати в закладки.

Метод POST (Відправити / Змінити)

Зазвичай ініціюється виключно натисканням кнопочки Submit в HTML-формі (<form method="POST">).

  1. Призначення: Для збереження нових сутностей у базі даних, зміни існуючих або виконання дій, які змінюють стан сервера (реєстрація).
  2. Передача даних: Дані “заховані” в тіло запиту (Request Body). Ви не бачите їх в адресному рядку браузера.
  3. Безпека: Саме через POST треба передавати реєстраційні дані та паролі, оскільки вони не світяться в URL (і не осідають в історії браузера чи в логах системних адміністраторів провайдера).
  4. Обмеження об’єму: Можна відправляти навіть кілька гігабайт інфи або файли (картинки, документи).
  5. Повторна відправка: Браузер перепитає (“Чи хочете ви перевідправити форму?”) при спробі оновити сторінку F5 для запобігання подвійній оплаті чи подвійному збереженню.

3. Суперглобальні масиви PHP та обробка $_GET

У PHP розробнику не потрібно вручну парсити ті загадкові текстові рядки протоколу HTTP і “різати” URL-и. Інтерпретатор PHP робить це автоматично ДО запуску вашого коду на файлі index.php. Він бере всі дані і сортує їх в особливі багатовимірні масиви, що називаються Суперглобальними.

Суперглобальні масиви — це вбудовані “з коробки” змінні в PHP, які завжди доступні у будь-якій частині коду (включаючи будь-яку вашу функцію, без необхідності писати слово global). Вони всі починаються з префіксу $_.

Основні з них:

Query String (Рядок запиту) і масив $_GET

Основним механізмом спілкування між сторінками через GET-метод є параметри Query String. Вони додаються в URL після знаку питання ?. Кожен параметр - це пара “ключ=значення”. Разом вони розділяються амперсандом &.

Приклад адреси (пошуковий запит): http://mysite.com/search.php?category=books&author=king

Коли користувач переходить за таким URL, PHP АВТОМАТИЧНО формує та заповнює суперглобальний асоціативний масив $_GET:

<?php
// PHP відпрацював, і масив $_GET гарантовано має такий вигляд:
// $_GET = [
//     'category' => 'books',
//     'author'   => 'king'
// ];

// Отже, ми як розробники можемо легко діставати ці змінні:
echo "Ви шукаєте категорію: " . $_GET['category'];
echo "Автор: " . $_GET['author'];

// ------------------------------------
// ВАЖЛИВА ПРАВИЛО БЕЗПЕКИ !!!
// Що як користувач зітре "?category=books" з адресного рядка?
// Наш код впаде з помилкою "Warning: Undefined array key 'category'"

// Завжди перевіряйте наявність ключа, або використовуйте оператор об'єднання (??):
$cat = $_GET['category'] ?? "Фільтрація вимкнена"; // Якщо ключа нема, поставити дефолт
echo "Поточна категорія: " . $cat;
?>

4. URL-кодування (URL-encoding) параметрів

В URL-адресу не можна просто так написати пробіл, кирилицю чи знаки &, #, =. Згідно зі специфікацією, ці знаки мають спеціальне системне значення. Вони повинні бути “закодовані” (переведені в безпечний латинський 16-й формат %hex).

Якщо ви хочете передати логін Іван Шевченко, браузер (або ви вручну при створенні лінки) повинні перетворити його за допомогою PHP-функції urlencode(). ?login=Іван%20Шевченко

Добра новина: під час “розбору” масиву, всередині $_GET['login'] PHP автоматично зробить декодування (URL Decode) у звичний для вас пробіл та Кирилицю! Вам не треба розкодовувати його назад.


Висновки

  1. Протокол HTTP не має пам’яті (Stateless) – сервер ставиться до кожного запиту (кліку у браузері) як до абсолютно нового, незважаючи на те, що користувач уже був тут раніше.
  2. GET-запити використовуються тільки для “Читання” даних. Всі передані клієнтом дані “світяться” в URL, вони не підходять для паролів чи великих обсягів тексту.
  3. Інтерпретатор PHP на старті опрацьовує всі GET параметри із URL (які знаходяться після символу ?) та будує зручний асоціативний масив, до якого розробники мають доступ у вигляді $_GET.
  4. Звертаючись до ключів, які прийшли від користувача ($_GET['id']), потрібно застосовувати перевірки існування параметра чи оператор об’єднання (??), оскільки користувач може стерти його з адресної строки вручну.
  5. Для передачі нелатинських символів (кирилиці) і пробілів в URL-параметрах, потрібно використовувати процес URL-encoding.

Джерела

  1. Методи запитів HTTP (MDN): https://developer.mozilla.org/ru/docs/Web/HTTP/Methods
  2. PHP Суперглобальні змінні та $_GET: https://www.php.net/manual/ru/language.variables.superglobals.php

Запитання для самоперевірки

  1. Поясніть сутність терміну “Stateless” у протоколі HTTP та аргументуйте, з якою проблемою стикнуться розробники інтернет-магазину при проєктуванні “Кошика покупок” через таку природу протоколу?
  2. Назвіть 3 ключові характеристики, які розрізняють метод розробки ресурсу через GET від POST. Крім способу “сховку” параметрів (URL vs Body), яка суттєва різниця у їхньому цільовому (семантичному) призначенні?
  3. Що таке Суперглобальний масив в контексті PHP? Чому нам не потрібно писати global $_GET у тілі невеликої власної function, щоб його побачити?
  4. Що робить оператор подвійного знака питання ($myAge = $_GET['age'] ?? 18;) і чому його використання є найкращою практикою під час роботи зі структурами даних, отриманими від зовнішнього клієнта (браузера)?
  5. Чим буде небезпечно відправляти форму авторизації (Логін, Пароль) методом GET? Де саме (як мінімум в 3 місцях комп’ютера або мережі) залишиться скомпрометована інформація про введені дані користувача?