Запросы и ответы HTTP
Браузер и сервер общаются по протоколу HTTP: браузер отправляет запрос, сервер возвращает ответ. PHP запускается на каждый запрос, получает его данные и формирует ответ. Понимая это, вы сможете не только выводить страницы, но и перенаправлять, отдавать файлы и строить API.
Примерам этого урока нужен веб-сервер, поэтому здесь они не запускаются.
Из чего состоит запрос
У запроса есть метод (GET, POST), адрес, заголовки и иногда тело. Всё это PHP кладёт в массив $_SERVER:
<?php
echo $_SERVER['REQUEST_METHOD']; // GET
echo $_SERVER['REQUEST_URI']; // /products?page=2GET используют для чтения страниц, POST — для отправки данных, которые что-то меняют.
Разная обработка методов
Один и тот же адрес может показывать форму и принимать её:
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
echo 'Форма отправлена';
} else {
echo 'Показываем форму';
}Код состояния
Ответ начинается с кода: 200 — всё хорошо, 404 — не найдено, 500 — ошибка сервера. Код задаёт функция http_response_code():
<?php
$product = null;
if ($product === null) {
http_response_code(404);
echo 'Товар не найден';
}Без этой строки страница «не найдено» ушла бы с кодом 200, и поисковик принял бы её за обычную.
Заголовки ответа
Заголовки сообщают браузеру, что он получил. Их отправляет функция header():
<?php
header('Content-Type: text/plain; charset=utf-8');
echo 'Обычный текст, а не HTML';Перенаправление
Заголовок Location отправляет браузер на другой адрес. После него программу завершают:
<?php
header('Location: /login');
exit;Перенаправление после успешной обработки формы обязательно: иначе обновление страницы отправит форму повторно.
Ответ в JSON
API отдаёт не страницы, а данные. Для этого указывают тип application/json и выводят результат json_encode():
<?php
header('Content-Type: application/json; charset=utf-8');
echo json_encode(['id' => 1, 'title' => 'Чай'], JSON_UNESCAPED_UNICODE);Тело запроса в JSON
Данные, присланные в формате JSON, в $_POST не попадают. Их читают из потока php://input:
<?php
$body = file_get_contents('php://input');
$data = json_decode($body, true) ?? [];
echo $data['title'] ?? 'Название не передано';Частая ошибка
Заголовки отправляются раньше содержимого страницы. Если до вызова header() уже что-то выведено — даже пробел или пустая строка перед <?php, — PHP выдаст предупреждение Cannot modify header information, и перенаправление не сработает. Вызывайте header() до любого вывода.