GET и POST в PHP: как узнать метод запроса и обрабатывать формы
Основы определения типа HTTP-запроса GET и POST в PHP
При разработке веб-форм часто возникает необходимость узнать, каким методом (GET или POST) был отправлен запрос. Это влияет на то, откуда читать данные (из $_GET или $_POST) и как обрабатывать информацию.
Как узнать тип запроса, используя суперглобальный массив $_SERVER?
Самый надежный и распространенный способ – прочитать ключ REQUEST_METHOD из массива $_SERVER. Этот ключ всегда содержит строку с именем метода HTTP-запроса (GET, POST, PUT, DELETE и т.д.).
<?php
$method = $_SERVER['REQUEST_METHOD'];
if ($method === 'GET') {
echo 'Запрос выполнен методом GET';
} elseif ($method === 'POST') {
echo 'Запрос выполнен методом POST';
} else {
echo "Другой метод: $method";
}
?>
Application form php (форма приложения на php)
Возможные проблемы:
- Если скрипт вызван через командную строку (CLI),
$_SERVER['REQUEST_METHOD']может быть не определён. Проверяйте черезisset()или используйтеphp_sapi_name(). - При некорректном HTTP-запросе (например, без строки метода) значение может отсутствовать. Рекомендуется проверять существование ключа.
Как определить метод через функцию filter_input()?
filter_input() позволяет безопасно получить значение из внешнего источника, в том числе из INPUT_SERVER. Это избавляет от необходимости вручную проверять isset().
<?php
$method = filter_input(INPUT_SERVER, 'REQUEST_METHOD', FILTER_SANITIZE_STRING);
if ($method === 'POST') {
echo 'Обработка POST-данных';
} else {
echo 'Другой метод или метод не определён';
}
?>
Input type name value php (обработка полей name и value в php-форме)
Типичные ошибки:
- Если не указан третий параметр (фильтр), функция вернет значение без фильтрации, что может быть небезопасно.
- При отсутствии ключа
REQUEST_METHODфункция вернётfalse, что может быть неожиданно. Используйте строгую проверку (===) или дополнительную проверку.
Можно ли определить метод по наличию данных в $_GET или $_POST?
Такой подход ненадёжен: GET-запрос может не содержать параметров, а POST-запрос может быть пустым. Однако в некоторых простых сценариях это допустимо.
<?php
if ($_POST) {
echo 'Вероятно, это POST (есть POST-данные)';
} elseif ($_GET) {
echo 'Вероятно, это GET (есть GET-параметры)';
} else {
echo 'Не удалось определить метод по данным';
}
?>
Input type submit php (кнопка submit в php-форме)
Ошибки этого подхода:
- Форма с методом GET и без полей не заполнит
$_GET, но метод останется GET. - Запрос DELETE или PUT может передать тело, но не будет ни GET, ни POST.
- Не стоит полагаться на такой способ в серьёзных проектах.
Как использовать объект запроса (PSR-7) для определения метода?
В современных фреймворках и библиотеках (например, Guzzle, Slim, Laravel) используется объект, реализующий Psr\Http\Message\ServerRequestInterface. У такого объекта есть метод getMethod().
<?php
use Psr\Http\Message\ServerRequestInterface;
function handleRequest(ServerRequestInterface $request) {
$method = $request->getMethod();
switch ($method) {
case 'GET':
echo 'Запрос GET';
break;
case 'POST':
echo 'Запрос POST';
break;
default:
echo "Метод $method не поддерживается";
}
}
?>
Проблемы и особенности:
- Требуется установка сторонних библиотек через Composer.
- В простых скриптах без фреймворка это избыточно.
- Объект запроса должен быть корректно создан из глобальных переменных (например, через
GuzzleHttp\Psr7\ServerRequest::fromGlobals()).
Цели и случаи использования каждого варианта
| Метод | Когда применять |
|---|---|
$_SERVER['REQUEST_METHOD'] | Базовые скрипты, самописные маршрутизаторы, простые обработчики форм |
filter_input(INPUT_SERVER, ...) | Если нужно строго контролировать тип и фильтрацию входных данных |
Проверка $_GET/$_POST | Только для быстрых прототипов, когда точно известно, что данные придут |
| PSR-7 Request Object | Проекты, использующие современные фреймворки, для единообразной обработки запросов |
Расширенные примеры определения типа HTTP-запроса в PHP
Пример 1. Обработка обоих методов в одном скрипте с проверкой
Скрипт принимает как GET-параметры для отображения формы, так и POST-данные для её обработки.
<?php
$method = $_SERVER['REQUEST_METHOD'];
if ($method === 'POST') {
// Обработка отправки формы
$name = trim($_POST['name'] ?? '');
$email = trim($_POST['email'] ?? '');
echo "Получены данные: Имя = $name, Email = $email";
} else {
// GET-запрос - показать форму
?>
<form method="POST" action="">
<input type="text" name="name" placeholder="Ваше имя">
<input type="email" name="email" placeholder="Email">
<button type="submit">Отправить</button>
</form>
<?php
}
?>
Результат при GET: HTML-форма Результат при POST: Получены данные: Имя = Иван, Email = ivan@example.com
Пример 2. Использование switch для нескольких методов
Реализация простого маршрутизатора, поддерживающего GET, POST и HEAD.
<?php
$method = $_SERVER['REQUEST_METHOD'];
switch ($method) {
case 'GET':
echo 'Отображение ресурса';
break;
case 'POST':
echo 'Создание ресурса';
break;
case 'HEAD':
header('Content-Length: 0');
exit;
default:
http_response_code(405);
echo 'Метод не поддерживается';
}
?>
При HEAD: пустой ответ с заголовком Content-Length: 0
Пример 3. Определение метода с помощью cURL (клиентская сторона)
Показывает, как отправить запрос и на сервере определить метод.
# Сохраните как client.php и server.php
// server.php
<?php
$method = $_SERVER['REQUEST_METHOD'];
echo 'Сервер получил метод: ' . $method;
?>
// client.php (выполняется из командной строки)
<?php
$ch = curl_init('http://localhost/server.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>
Вывод client.php: Сервер получил метод: POST
Пример 4. Проверка типа запроса с помощью PHP-фильтров и обработка ошибок
Безопасное получение метода и установка значения по умолчанию.
<?php
$method = filter_input(INPUT_SERVER, 'REQUEST_METHOD', FILTER_SANITIZE_STRING);
if ($method === false || $method === null) {
// Если метод не определён, считаем, что это GET (например, при CLI)
$method = 'GET';
error_log('Внимание: REQUEST_METHOD не найден, установлен GET');
}
echo "Используется метод: $method";
?>
Вывод при запуске из CLI: Используется метод: GET
Пример 5. Полноценная обработка формы с защитой от подмены метода
Используется скрытое поле _method для имитации PUT/DELETE, но проверка реального метода остаётся на REQUEST_METHOD.
<?php
$method = $_SERVER['REQUEST_METHOD'];
if ($method === 'POST' && isset($_POST['_method'])) {
// Разрешаем переопределение только для некоторых методов
$allowedOverrides = ['PUT', 'DELETE', 'PATCH'];
if (in_array(strtoupper($_POST['_method']), $allowedOverrides)) {
$method = strtoupper($_POST['_method']);
}
}
echo "Реальный/переопределённый метод: $method";
?>
<form method="POST" action="">
<input type="hidden" name="_method" value="DELETE">
<button type="submit">Удалить запись</button>
</form>
При нажатии кнопки: Реальный/переопределённый метод: DELETE
Пример 6. Использование PSR-7 с библиотекой guzzlehttp/psr7
Создание серверного запроса из глобальных переменных и получение метода.
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Psr7\ServerRequest;
$request = ServerRequest::fromGlobals();
$method = $request->getMethod();
echo "Метод из PSR-7: $method";
?>
Вывод: Метод из PSR-7: POST (если отправлена форма) или GET