Получение метода HTTP запроса в PHP: практические примеры
Основы работы с методом HTTP запроса в PHP
Для определения метода HTTP запроса в PHP используется суперглобальный массив $_SERVER['REQUEST_METHOD']. Это наиболее простой и распространённый способ, который предоставляет сервер. Значение может быть строкой: 'GET', 'POST', 'PUT', 'DELETE', 'PATCH' и другими.
<?php
$method = $_SERVER['REQUEST_METHOD'];
echo 'Тип запроса: ' . $method;
?>
Source query php (источник запроса в php)
Данный код выводит тип запроса, с которым клиент обратился к скрипту. Например, при отправке формы методом POST будет выведено 'POST'. При переходе по ссылке - 'GET'. Это базовое решение, которое подходит для большинства случаев, когда необходимо различить GET и POST запросы.
Альтернативные варианты получения метода
Как получить метод запроса без прямого обращения к $_SERVER?
Можно использовать функцию filter_input(), которая безопаснее извлекает данные:
<?php
$method = filter_input(INPUT_SERVER, 'REQUEST_METHOD', FILTER_SANITIZE_STRING);
if ($method) {
echo 'Метод: ' . $method;
} else {
echo 'Метод не определён';
}
?>
Php request url (url запроса в php)
Этот вариант фильтрует значение, убирая потенциально опасные символы. Используется в проектах, где важна безопасная обработка входящих данных.
Проблема: Если в $_SERVER['REQUEST_METHOD'] отсутствует, filter_input вернёт NULL или false. Необходимо проверять результат.
Решение: Применять проверку на isset или использовать оператор объединения с null (??).
$method = filter_input(INPUT_SERVER, 'REQUEST_METHOD') ?? 'GET';
Request method php (метод http запроса в php)
Как обработать запросы PUT, DELETE и PATCH, если они не поддерживаются стандартно?
Веб-сервер может не передавать эти методы напрямую. Часто их эмулируют через POST-запрос с полем _method или заголовком X-HTTP-Method-Override.
<?php
$method = $_SERVER['REQUEST_METHOD'];
if ($method === 'POST' && isset($_POST['_method'])) {
$method = strtoupper($_POST['_method']);
}
echo 'Реальный метод: ' . $method;
?>
пример формы php (примеры html-форм с php)
Этот приём используется в фреймворках (Laravel, Symfony) для поддержки RESTful маршрутизации в HTML-формах, которые могут отправлять только GET и POST.
Ошибка: Использование недопустимого метода, например 'OPTIONS' или 'HEAD', может вызвать непредвиденное поведение.
Решение: Проверять метод на соответствие ожидаемому набору: in_array($method, ['GET','POST','PUT','DELETE','PATCH']).
Как определить метод, если используется php://input для PUT запросов?
Для методов PUT и PATCH данные передаются в теле запроса. Получить их можно через поток php://input.
<?php
if ($_SERVER['REQUEST_METHOD'] === 'PUT') {
$data = file_get_contents('php://input');
parse_str($data, $putData);
print_r($putData);
}
?>
Этот подход необходим, когда клиент отправляет данные в формате application/x-www-form-urlencoded или multipart/form-data через PUT.
Проблема: При использовании file_get_contents('php://input') для PUT, он может прочитать только один раз (поток не поддерживает повторное чтение).
Решение: Сохранять прочитанные данные в переменную и не обращаться к php://input повторно.
Цели и случаи использования каждого варианта
Определение метода HTTP необходимо для построения REST API, обработки форм с разными действиями, маршрутизации запросов в MVC-структуре. Вариант с $_SERVER['REQUEST_METHOD'] подходит для простых скриптов, а вариант с filter_input - для проектов с повышенными требованиями к безопасности. Эмуляция методов через _method позволяет работать с RESTful маршрутами в браузерных формах. Чтение тела PUT/PATCH через php://input обязательно при получении данных, не помещённых в суперглобальные массивы.
Расширенные примеры работы с методами HTTP в PHP
Пример 1: Маршрутизация на основе метода
Реализация простого обработчика, который возвращает разные ответы в зависимости от метода.
<?php
$method = $_SERVER['REQUEST_METHOD'];
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
switch ($method) {
case 'GET':
echo "Получение ресурса: $path";
break;
case 'POST':
echo "Создание ресурса: $path";
break;
case 'PUT':
echo "Обновление ресурса: $path";
break;
case 'DELETE':
echo "Удаление ресурса: $path";
break;
default:
http_response_code(405);
echo "Метод не поддерживается: $method";
break;
}
?>
// При GET-запросе к /api/users: Получение ресурса: /api/users // При POST-запросе к /api/users: Создание ресурса: /api/users
Данный код демонстрирует базовую маршрутизацию. Важно устанавливать корректный HTTP-статус (405 Method Not Allowed) при неподдерживаемом методе.
Пример 2: Обработка JSON-данных для POST, PUT, PATCH
Современные API часто передают данные в формате JSON. Для его получения необходимо прочитать php://input и декодировать.
<?php
$method = $_SERVER['REQUEST_METHOD'];
$input = file_get_contents('php://input');
$data = json_decode($input, true);
if (in_array($method, ['POST', 'PUT', 'PATCH'])) {
if ($data === null && json_last_error() !== JSON_ERROR_NONE) {
http_response_code(400);
echo 'Неверный формат JSON';
exit;
}
echo 'Получены данные: ' . print_r($data, true);
} else {
http_response_code(405);
echo 'Метод не принимает тело запроса';
}
?>
// Отправка PUT-запроса с телом {"name":"Alice"}:
Получены данные: Array
(
[name] => Alice
)
Обратите внимание: проверка json_last_error() позволяет избежать ошибок при декодировании повреждённого JSON.
Пример 3: Эмуляция методов через заголовок X-HTTP-Method-Override
Некоторые HTTP-клиенты и прокси не поддерживают PUT/DELETE. В этом случае можно использовать заголовок.
<?php
$method = $_SERVER['REQUEST_METHOD'];
if (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
$override = strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']);
if (in_array($override, ['PUT', 'DELETE', 'PATCH'])) {
$method = $override;
}
}
// Теперь $method содержит эмулированный метод
echo "Текущий метод: $method";
?>
// Если клиент отправляет POST-запрос с заголовком X-HTTP-Method-Override: PUT Текущий метод: PUT
Такой подход применяется в некоторых веб-фреймворках для обеспечения совместимости.
Пример 4: Извлечение метода из строки запроса (для CLI или тестов)
При запуске скрипта из командной строки $_SERVER['REQUEST_METHOD'] может отсутствовать. Можно задавать метод через переменную окружения.
<?php
$method = getenv('REQUEST_METHOD') ?: ($_SERVER['REQUEST_METHOD'] ?? 'CLI');
echo "Метод: $method";
?>
// Запуск из терминала: REQUEST_METHOD=GET php script.php Метод: GET // Без переменной окружения: Метод: CLI
Этот приём полезен для тестирования API-скриптов вручную или в автоматических тестах.
Пример 5: Безопасное сравнение метода без уязвимости к загрязнению типа
При проверке метода стоит избегать прямого сравнения с пользовательским вводом. Используйте строгое сравнение.
<?php
$method = $_SERVER['REQUEST_METHOD'] ?? '';
if ($method === 'POST') {
// обработка формы
} elseif ($method === 'GET') {
// отображение страницы
}
// Не используйте if ($method == $_POST['_method']) без валидации
?>
Строгое сравнение (===) предотвращает случайное совпадение с false, null или пустой строкой.
Пример 6: Обработка всех методов через единый шлюз (front controller)
<?php
$method = $_SERVER['REQUEST_METHOD'];
$uri = $_SERVER['REQUEST_URI'];
$routes = [
'GET' => [
'/users' => 'listUsers',
'/user/{id}' => 'getUser',
],
'POST' => [
'/users' => 'createUser',
],
'PUT' => [
'/user/{id}' => 'updateUser',
],
'DELETE' => [
'/user/{id}' => 'deleteUser',
]
];
// Упрощённая маршрутизация (без разбора параметров)
if (isset($routes[$method][$uri])) {
$handler = $routes[$method][$uri];
echo "Вызов обработчика: $handler";
} else {
http_response_code(404);
echo 'Маршрут не найден';
}
?>
// Для GET /users: Вызов обработчика: listUsers // Для DELETE /user/123 (если маршрут не описан как точное совпадение): Маршрут не найден
Этот пример демонстрирует, как метод используется в front controller для диспетчеризации запросов. В реальных проектах применяются регулярные выражения или библиотеки маршрутизации.
Пример 7: Определение поддерживаемых методом типов содержимого
<?php
$method = $_SERVER['REQUEST_METHOD'];
$contentType = $_SERVER['CONTENT_TYPE'] ?? '';
if ($method === 'POST' || $method === 'PUT' || $method === 'PATCH') {
if (strpos($contentType, 'application/json') !== false) {
$data = json_decode(file_get_contents('php://input'), true);
} elseif (strpos($contentType, 'application/x-www-form-urlencoded') !== false) {
parse_str(file_get_contents('php://input'), $data);
} else {
http_response_code(415);
echo 'Неподдерживаемый Content-Type';
exit;
}
print_r($data);
}
?>
// Для POST с Content-Type: application/json; charset=utf-8 // выведет декодированный массив.
Код показывает, как метод влияет на способ чтения данных и как обрабатывать разные MIME-типы.