PHP Manual

Методи передачі даних (GET і POST)

26. 11. 2019

Obsah článku

Крім звичайних змінних, в PHP є ще так звані **суперглобальні змінні**, які несуть в собі інформацію про викликану в даний момент сторінку і дані, які ми передаємо.

Як правило, у нас є форма на сторінці, яку користувач заповнює, і ми хочемо передати ці дані на веб-сервер, де ми обробляємо їх на PHP.

Для цього найчастіше використовують 3 способи:

  • GET ~ дані передаються в URL в якості параметрів
  • POST ~ дані передаються приховано разом із запитом до сторінки
  • Ajax POST ~ асинхронна обробка JavaScript

Метод GET - $_GET

Дані, що передаються методом GET, видно в URL (як параметри після знаку питання), максимальна довжина - 1024 символи в Internet Explorer (інші браузери майже не обмежують, але більші тексти таким чином передавати не варто). Перевагою цього способу є насамперед простота (ви бачите, що ви надсилаєте) та можливість надати посилання на результат обробки. Дані відправляються в змінну.

Адреса сторінки, що приймає, може виглядати наступним чином:

https://____________.com/script.php?promenna=obsah&promenna2=obsah

У PHP ми можемо тоді, наприклад, записати значення параметра variable наступним чином:

echo $_GET['променад']; // виводить "content"

Суворе попередження: Такий спосіб запису даних безпосередньо на HTML-сторінку не є безпечним, оскільки ми можемо передати, наприклад, HTML-код в URL, який буде записаний на сторінку, а потім виконаний.

Ми повинні завжди обробляти дані перед будь-яким виводом на сторінку, для цього використовується функція htmlspecialchars().

Наприклад: echo htmlspecialchars($_GET['variable']);.

Метод POST - $_POST

Дані, що відправляються методом POST, не відображаються в URL, що вирішує проблему максимальної довжини даних, що відправляються. Для відправки полів форми завжди слід використовувати метод POST, оскільки це забезпечить невидимість, наприклад, паролів і неможливість надання посилання на сторінку, що обробляє результат того чи іншого введення.

Дані доступні у змінній $_POST і використовуються так само, як і для методу GET.

Перевірка існування відправлених даних

Перед обробкою будь-яких даних ми повинні спочатку переконатися, що дані дійсно були відправлені, інакше ми отримаємо доступ до до неіснуючої змінної, що викликало б повідомлення про помилку.

Для перевірки існування змінної використовується функція isset().

if (isset($_GET['Ім'я'])) {
echo 'Ваше ім'я:' . htmlspecialchars($_GET['Ім'я']);
} else {
echo 'Прізвище не вказано.';
}

Форма введення даних

Форма виконана на мові HTML, а не на PHP. Він може бути на звичайній HTML-сторінці. Всю "магію" виконує PHP-скрипт, який приймає дані.

Для прикладу можна використати форму для отримання 2 чисел, відправлених методом GET:

<form action="script.php" method="get">
První číslo: <input type="text" name="x">
Druhé číslo: <input type="text" name="y">
<input type="submit" value="Sečíst čísla">
</form>

У першому рядку можна побачити, куди будуть відправлені дані і яким способом.

Наступні 2 рядки - це прості елементи форми, зверніть увагу на атрибут name="", там знаходиться ім'я змінної, яка буде зберігати те, що зараз знаходиться у формі.

Далі йде кнопка відправки даних (обов'язкова) і закриваючий HTML-тег форми (обов'язковий, щоб браузер знав, що ще відправляти, а що ні).

На одній сторінці може бути будь-яка кількість форм, і вони не можуть бути вкладеними. Якщо відбувається вкладання, завжди відправляється найбільш вкладена форма, а решта ігноруються.

Обробка форм на сервері

Тепер ми маємо готову HTML-форму і відправляємо її на скрипт script.php, який отримує дані за допомогою методу GET. Адреса запиту сторінки може мати такий вигляд:

https://________.com/script.php?x=5&y=3

script.php.

$x = $_GET['x']; // 5
$y = $_GET['y']; // 3
echo $x + $y; // виводить 8

Правильно, спочатку слід перевірити, що обидва поля форми заповнені, це робиться за допомогою функції isset():

if (isset($_GET['x']) && isset($_GET['y'])) {
$x = $_GET['x']; // 5
$y = $_GET['y']; // 3
echo $x + $y; // виводить 8
} else {
echo 'Форма була заповнена невірно.';
}

Підказка:** У конструкцію isset() можна передати декілька параметрів, щоб перевірити, чи всі вони існують.

Тому замість isset($_GET['x]) && isset($_GET['y]) можна просто вказати:

isset($_GET['x], $_GET['y]).

Обробка даних, отриманих методом POST

Якщо дані отримані методом POST, то URL скрипта, який буде оброблятися, завжди буде виглядати наступним чином:

https://________.com/script.php

І ніколи інакше. Просто ні. Дані приховані в HTTP-запиті, і ми їх не бачимо.

З міркувань безпеки для відправки логінів і паролів необхідно використовувати прихований метод POST.

Безпека:** Якщо ви працюєте з паролями на своєму сайті, форма входу та реєстрації повинна бути розміщена на HTTPS і ви повинні хешувати паролі відповідним чином (наприклад, за допомогою BCrypt).

Обробка ajax-запитів

У деяких випадках при обробці ajax-запитів може бути нелегко отримати дані. Причина в тому, що ajax бібліотеки зазвичай відправляють дані у вигляді json payload, в той час як суперглобальна змінна $_POST містить тільки дані форми.

Доступ до даних все ще можна отримати, подробиці я описав в статті Обробка ajax POST запитів.

Отримання вихідної сировини

Іноді може статися так, що користувач надсилає запит, використовуючи невідповідний HTTP-метод, і додає поверх нього свої дані. Або, наприклад, надсилає бінарний файл, або погані HTTP-заголовки.

Для такого випадку добре використовувати нативний ввід, який в PHP отримується наступним чином:

$input = file_get_contents('php://input');

Під час реалізації бібліотеки REST API я також зіткнувся з низкою особливих випадків, коли різні типи веб-серверів неправильно визначали вхідні HTTP-заголовки, або користувач некоректно відправляв дані форми тощо.

Для цього випадку мені вдалося реалізувати таку функцію, яка вирішує практично всі випадки (реалізація залежить від Nette\Http\RequestFactory, але ви можете замінити цю залежність на щось інше у вашому конкретному проекті):

/**
* Отримує POST-дані безпосередньо з HTTP-заголовка, або намагається розібрати дані з рядка.
* Деякі застарілі клієнти надсилають дані у форматі json, який має формат базового рядка, тому приведення полів до масиву є обов'язковим.
*
* @повертається масив<string|int, mixed>
*/
private function getBodyParams(string $method): array
{
if ($method === 'GET' || $method === 'ВИДАЛИТИ') {
return [];
}
$request = (new RequestFactory())->fromGlobals();
$return = array_merge((array) $request->getPost(), $request->getFiles());
try {
$post = array_keys($_POST)[0] ?? '';
if (str_starts_with($post, '{') && str_ends_with($post, '}')) { // підтримка застарілих клієнтів
$json = json_decode($post, true, 512, JSON_THROW_ON_ERROR);
if (is_array($json) === false) {
throw new LogicException('Json не є допустимим масивом.');
}
unset($_POST[$post]);
foreach ($json as $key => $value) {
$return[$key] = $value;
}
}
} catch (Throwable $e) {
// Мовчання - золото.
}
try {
$input = (string) file_get_contents('php://input');
if ($input !== '') {
$phpInputArgs = (array) json_decode($input, true, 512, JSON_THROW_ON_ERROR);
foreach ($phpInputArgs as $key => $value) {
$return[$key] = $value;
}
}
} catch (Throwable $e) {
// Мовчання - золото.
}
return $return;
}

Jan Barášek   Více o autorovi

Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.

Rád vám pomůžu:

Související články

1.
6.
Status:
All systems normal.
2024