Введение: почему важно знать, какой запрос пришёл на сервер?
Представьте, что вы — швейцар в элитном доме. К вам приходят разные люди: одни просто хотят посмотреть список жильцов (GET), другие — добавить нового жильца (POST), третьи — обновить данные (PUT), а четвёртые — удалить запись (DELETE). Если вы перепутаете действия, начнётся хаос. Примерно то же самое происходит в PHP, когда вы строите современное веб-приложение или REST API.
Вопрос "Detecting request type in PHP (GET, POST, PUT or DELETE)" — один из самых популярных на Stack Overflow (тысячи просмотров). И это не случайно. Новички часто пишут: if ($_POST) — и ловят баги, когда приходит PUT или DELETE. Сегодня мы раз и навсегда разберёмся, как грамотно определять метод HTTP-запроса в PHP, чтобы ваш код был надёжным и профессиональным.
Статья написана для образовательного сайта PythonLib, но тема универсальна. Поехали!
Что такое HTTP-методы и зачем их различать?
HTTP — это протокол, по которому браузер (или клиент) общается с сервером. Каждый запрос имеет метод (глагол), который говорит серверу, что именно нужно сделать:
- GET — получить данные (читать). Безопасный, идемпотентный.
- POST — отправить данные (создать новый ресурс).
- PUT — полностью заменить ресурс (обновить).
- DELETE — удалить ресурс.
- PATCH — частично обновить (реже).
В классических HTML-формах браузер поддерживает только GET и POST. Но в REST API (например, для мобильных приложений или AJAX) активно используются все методы. Если вы пишете универсальный бэкенд, вам нужно уметь их различать.
Самый главный инструмент: $_SERVER['REQUEST_METHOD']
В PHP вся информация о запросе хранится в суперглобальном массиве $_SERVER. Ключ REQUEST_METHOD содержит строку с названием метода: 'GET', 'POST', 'PUT', 'DELETE' и т.д.
Вот базовый пример:
<?php
$method = $_SERVER['REQUEST_METHOD'];
echo "Тип запроса: " . $method;
?>
Запустите этот код на своём сервере. Если вы откроете страницу в браузере — увидите GET. Если отправите форму с method="POST" — увидите POST. Всё гениально просто.
Но это только начало. Давайте разберём, как правильно строить логику на основе метода.
Практический пример: маршрутизатор для REST API
Допустим, мы пишем простой API для управления списком задач (to-do list). У нас есть один endpoint — /api/tasks. В зависимости от метода запроса мы выполняем разные действия:
- GET — вернуть список всех задач.
- POST — создать новую задачу.
- PUT — обновить существующую задачу (заменить целиком).
- DELETE — удалить задачу.
Вот как это выглядит в коде:
<?php
// Определяем метод запроса
$method = $_SERVER['REQUEST_METHOD'];
// Маршрутизация
switch ($method) {
case 'GET':
// Обработка GET-запроса
echo "Вывод списка задач...";
// Здесь логика получения данных из БД
break;
case 'POST':
// Обработка POST-запроса
echo "Создание новой задачи...";
// $_POST содержит данные формы
$title = $_POST['title'] ?? '';
// Логика сохранения в БД
break;
case 'PUT':
// Обработка PUT-запроса
echo "Обновление задачи...";
// ВАЖНО: PUT-данные не попадают в $_POST!
// Их нужно читать из php://input
$putData = json_decode(file_get_contents('php://input'), true);
$id = $putData['id'] ?? null;
// Логика обновления
break;
case 'DELETE':
// Обработка DELETE-запроса
echo "Удаление задачи...";
// DELETE также передаёт данные через php://input
$deleteData = json_decode(file_get_contents('php://input'), true);
$id = $deleteData['id'] ?? null;
// Логика удаления
break;
default:
// Если метод не поддерживается
http_response_code(405); // Method Not Allowed
echo json_encode(['error' => 'Метод не поддерживается']);
break;
}
?>
Обратите внимание: для GET и POST данные доступны через суперглобальные массивы $_GET и $_POST. А для PUT и DELETE — нет. Почему? Потому что PHP по умолчанию заполняет $_POST только для запросов с Content-Type: application/x-www-form-urlencoded или multipart/form-data, и только для метода POST. Для остальных методов нужно читать "сырое" тело запроса через php://input.
Подводные камни: что важно знать новичку
1. Не все сервера поддерживают PUT и DELETE из коробки
В старых конфигурациях или на некоторых хостингах может потребоваться дополнительная настройка. Но в 99% случаев современный PHP (7.4+) и веб-сервер (Apache/Nginx) прекрасно понимают все стандартные методы.
2. Как быть с AJAX-запросами из JavaScript?
Если вы отправляете запрос из браузера через fetch() или XMLHttpRequest, вы можете указать любой метод. Пример на JavaScript:
fetch('/api/tasks', {
method: 'PUT',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({id: 1, title: 'Новая задача'})
});
На стороне PHP вы получите $_SERVER['REQUEST_METHOD'] = 'PUT'. Отлично работает.
3. Эмуляция методов через скрытое поле формы
Иногда (например, в Laravel или Symfony) для HTML-форм используют скрытое поле _method. Это костыль, потому что браузеры не умеют отправлять формы с методами, отличными от GET и POST. Выглядит это так:
<form action="/tasks/1" method="POST">
<input type="hidden" name="_method" value="PUT">
<input type="text" name="title">
<button type="submit">Обновить</button>
<