$_GET, $_POST и формы
В ресторане заказ приходит на бланке. Посетитель вписывает в него блюдо, количество и пожелания. Бланк может прийти заполненным наполовину, совсем пустым или заполненным чужой рукой — повар узнает об этом, только когда прочитает его.
В PHP такие бланки — это данные запроса. Давайте посмотрим, где они лежат и чего от них ждать.
Параметры в адресе: $_GET
Адрес может нести данные. Параметры запроса — это всё, что стоит после ?: пары «имя=значение», разделённые знаком &. Для адреса /menu.php?page=3&city= PHP ещё до первой строки вашей программы кладёт параметры в массив $_GET.
$_GET — суперглобальный массив: PHP заполняет его сам, и он виден в любом месте программы, даже внутри функции.
В терминале запроса нет, поэтому в примерах первая строка изображает запрос: она сама присваивает $_GET. На встроенном сервере эту строку убирают, и массив заполняет PHP.
<?php
$_GET = ['page' => '3', 'city' => ''];
var_dump($_GET['page'] ?? 1); // string(1) "3"
var_dump($_GET['sort'] ?? 'name'); // string(4) "name"
var_dump($_GET['city'] ?? 'Paris'); // string(0) ""Первая строка соответствует адресу ?page=3&city=. Параметр приходит в одном из трёх видов, и ?? ведёт себя в них по-разному.
Параметр есть
$_GET['page'] — строка '3', а не число. Значение параметра приходит строкой, даже если в нём одни цифры. Массивом оно приходит только у параметра с [] в имени, как в tags[]=a. ?? видит, что ключ есть и значение не null, и отдаёт '3'.
Параметра нет
Параметра sort в адресе не было, поэтому в $_GET нет такого ключа. Обычное чтение $_GET['sort'] дало бы предупреждение Warning: Undefined array key "sort". Как вы уже знаете, ?? сначала проверяет ключ и молча берёт значение справа — 'name'.
Параметр пустой
Запись city= передаёт ключ city с пустой строкой. Так же приходит поле формы, которое посетитель оставил пустым. ?? реагирует только на отсутствующий ключ и null, поэтому оставляет пустую строку и не подставляет 'Paris'.
Строка в число: (int)
Номер страницы нужен как число, поэтому значение приводят к int:
$_GET = ['page' => '3', 'size' => 'abc'];
$page = (int) ($_GET['page'] ?? 1);
$size = (int) ($_GET['size'] ?? 10);
var_dump($page); // int(3)
var_dump($size); // int(0)Разберём по шагам:
- Скобки вокруг
$_GET['page'] ?? 1нужны, чтобы(int)применялся к результату??. - Строка
'3'превращается вint(3). - В
sizeпосетитель вписалabc, и(int)молча даёт0.
Приведение делает из строки число, но не проверяет, разумное ли это число. Страница 0 или размер 0 — ошибка, о которой PHP не сообщит.
Формы и $_POST
Форма — это бланк заказа на самой странице. Когда посетитель нажимает кнопку формы с method="post", браузер отправляет значения полей не в адресе, а в теле запроса. PHP кладёт их в суперглобальный массив $_POST по именам из атрибута name.
<?php
$_SERVER['REQUEST_METHOD'] = 'POST';
$_POST = ['dish' => 'Soup', 'qty' => '2'];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$dish = $_POST['dish'] ?? '';
$qty = (int) ($_POST['qty'] ?? 1);
echo $qty, ' x ', $dish, "\n"; // 2 x Soup
}
?>
<form method="post">
<input name="dish">
<input name="qty">
<button>Order</button>
</form>Две строки после <?php изображают отправленную форму, остальное — настоящий шаблон:
$_SERVER['REQUEST_METHOD']хранит метод запроса:'GET', когда страницу открыли по адресу, и'POST', когда отправили такую форму.- Если форму отправили, программа читает поля через
??и приводит количество к числу. - Ниже
?>стоит сама форма. Адреса у неё нет, поэтому браузер отправит её на ту же страницу.
Метод GET подходит для чтения: номер страницы, поиск, сортировка. Метод POST — для данных, которые что-то меняют: заказ, комментарий, регистрация.
Чем GET отличается от POST, часто спрашивают на собеседовании. Параметры GET видны в адресе и остаются в истории браузера, а поля POST идут в теле запроса.
Содержимое $_GET и $_POST задаёт посетитель. Он может стереть параметр, вписать ?page=abc или отправить форму с полями, которых на странице нет. В картинке с рестораном это бланк, заполненный чужой рукой, и доверять ему нельзя.
Только здесь картинка неточна: повар видит, кто отдал бланк, а программа не знает, кто прислал запрос. Отправить запрос можно и в обход вашей формы.
Частая ошибка
Параметр читают без ??:
<?php
$_GET = [];
$page = (int) $_GET['page']; // ✗
echo $page, "\n";Warning: Undefined array key "page"Посетитель открыл адрес без ?page=, и ключа в $_GET нет. PHP выдаёт предупреждение и читает null, (int) null даёт 0, и программа печатает 0. Исправление — значение по умолчанию: $page = (int) ($_GET['page'] ?? 1);.
Главное
$_GETхранит параметры из адреса,$_POST— поля отправленной формы, и параметр без[]в имени приходит в них строкой.- Отсутствующий параметр — это отсутствующий ключ:
$_GET['page'] ?? 1даёт значение по умолчанию без предупреждения. - Пустой параметр
city=— это ключ с пустой строкой, и??его не заменяет. (int)превращает строку в число, но'abc'молча становится0: приведение — ещё не проверка.