К содержанию
Medusa
Документация

HTTP-запросы

Medusa\Http\Request используется для чтения данных входящего HTTP-запроса.

Инициализация класса

Во время HTTP-запроса объект Request уже доступен в глобальной переменной $REQUEST.

/** @var Medusa\Http\Request $REQUEST */

global $REQUEST;

Получение заголовков запроса

Метод $REQUEST->getHeaders() возвращает все заголовки запроса.

Запрос:

GET / HTTP/1.1
Host: localhost:8001

Код/Результат:

$headers = $REQUEST->getHeaders();

echo print_r($headers, true);
Array
(
  [User-Agent] => PostmanRuntime/7.37.3
  [Accept] => */*
  [Postman-Token] => 5ef52a6e-74cb-4717-a4cc-ac244118a90d
  [Host] => localhost:8001
  [Accept-Encoding] => gzip, deflate, br
  [Connection] => keep-alive
)

Метод $REQUEST->getHeaders($key) возвращает конкретный заголовок.

Запрос:

GET / HTTP/1.1
Host: localhost:8001

Код/Результат:

$userAgent = $REQUEST->getHeaders('User-Agent');

echo $userAgent;
PostmanRuntime/7.37.3

Получение метода запроса

Метод $REQUEST->getMethod() возвращает HTTP-метод текущего запроса.

Запрос:

POST / HTTP/1.1
Host: localhost:8001

Код/Результат:

$method = $REQUEST->getMethod();

echo $method;
POST

Получение параметров запроса

  • Получение GET-параметров:

    • Запрос:

      GET /?limit=1&offset=0 HTTP/1.1
      Host: localhost:8001
    • Код/Результат:

      $limit = $REQUEST->get('limit', Request::GET);
      $offset = $REQUEST->get('offset', Request::GET);
      
      echo sprintf("limit %d\noffset %d", $limit, $offset);
      limit 1
      offset 0
  • Получение POST multipart/form-data:

    • Запрос:

      POST / HTTP/1.1
      Host: localhost:8001
      Content-Length: 250
      Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
      
      ------WebKitFormBoundary7MA4YWxkTrZu0gW
      ------WebKitFormBoundary7MA4YWxkTrZu0gW
      Content-Disposition: form-data; name="file"; filename="photo.png"
      Content-Type: <Content-Type header here>
      
      (data)
      ------WebKitFormBoundary7MA4YWxkTrZu0gW--
    • Код/Результат:

      $name = $REQUEST->get('name', Request::POST);
      $uploadedFile = $REQUEST->get('file', Request::FILE);
      
      echo sprintf("name %s\nfile %s", $name, $uploadedFile[0]['tmp_name']);
      name photo-1
      file /tmp/phpg1k6rsml8fob5VF9kvf
  • Получение POST-параметров x-www-form-urlencoded:

    • Запрос:

      POST / HTTP/1.1
      Host: localhost:8001
      Content-Type: application/x-www-form-urlencoded
      Content-Length: 20
      
      name=App&email=app%40mail.ru
    • Код/Результат:

      $name = $REQUEST->get('name', Request::POST);
      $email = $REQUEST->get('email', Request::POST);
      
      echo sprintf("name %s\nemail %s", $name, $email);
      name App
      email app@mail.ru
  • Получение JSON-данных POST-запроса:

    • Запрос:

      POST / HTTP/1.1
      Host: localhost:8001
      Content-Type: application/json
      Content-Length: 65
      
      {
        "data": {
          "name": "App",
          "email": "app@mail.ru"
        }
      }
    • Код/Результат:

      $payload = $REQUEST->get('data', Request::POST);
      
      echo json_encode($payload);
      {"name":"App","email":"app@mail.ru"}
  • Получение PUT-параметров x-www-form-urlencoded:

    • Запрос:

      PUT / HTTP/1.1
      Host: localhost:8001
      Content-Type: application/x-www-form-urlencoded
      Content-Length: 20
      
      name=App&email=app%40mail.ru
    • Код/Результат:

      $name = $REQUEST->get('name', Request::PUT);
      $email = $REQUEST->get('email', Request::PUT);
      
      echo sprintf("name %s\nemail %s", $name, $email);
      name App
      email app@mail.ru
  • Получение JSON-данных PUT-запроса:

    • Запрос:

      PUT / HTTP/1.1
      Host: localhost:8001
      Content-Type: application/json
      Content-Length: 65
      
      {
        "data": {
          "name": "App",
          "email": "app@mail.ru"
        }
      }
    • Код/Результат:

      $payload = $REQUEST->get('data', Request::PUT);
      
      echo json_encode($payload);
      {"name":"App","email":"app@mail.ru"}
  • Получение PATCH-параметров x-www-form-urlencoded:

    • Запрос:

      PATCH / HTTP/1.1
      Host: localhost:8001
      Content-Type: application/x-www-form-urlencoded
      Content-Length: 20
      
      name=App&email=app%40mail.ru
    • Код/Результат:

      $name = $REQUEST->get('name', Request::PATCH);
      $email = $REQUEST->get('email', Request::PATCH);
      
      echo sprintf("name %s\nemail %s", $name, $email);
      name App
      email app@mail.ru
  • Получение JSON-данных PATCH-запроса:

    • Запрос:

      PATCH / HTTP/1.1
      Host: localhost:8001
      Content-Type: application/json
      Content-Length: 65
      
      {
        "data": {
          "name": "App",
          "email": "app@mail.ru"
        }
      }
    • Код/Результат:

      $payload = $REQUEST->get('data', Request::PATCH);
      
      echo json_encode($payload);
      {"name":"App","email":"app@mail.ru"}
  • Получение DELETE-параметров x-www-form-urlencoded:

    • Запрос:

      DELETE / HTTP/1.1
      Host: localhost:8001
      Content-Type: application/x-www-form-urlencoded
      Content-Length: 20
      
      name=App&email=app%40mail.ru
    • Код/Результат:

      $name = $REQUEST->get('name', Request::DELETE);
      $email = $REQUEST->get('email', Request::DELETE);
      
      echo sprintf("name %s\nemail %s", $name, $email);
      name App
      email app@mail.ru
  • Получение JSON-данных DELETE-запроса:

    • Запрос:

      DELETE / HTTP/1.1
      Host: localhost:8001
      Content-Type: application/json
      Content-Length: 65
      
      {
        "data": {
          "name": "App",
          "email": "app@mail.ru"
        }
      }
    • Код/Результат:

      $payload = $REQUEST->get('data', Request::DELETE);
      
      echo json_encode($payload);
      {"name":"App","email":"app@mail.ru"}
  • Получение binary-данных для POST/PUT/PATCH с заголовком Content-Type: application/octet-stream:

    • Запросы с данными:

      POST / HTTP/1.1
      Host: localhost:8001
      Content-Type: application/octet-stream
      Content-Length: 25
      
      тестовая текстовая строка
      PUT / HTTP/1.1
      Host: localhost:8001
      Content-Type: application/octet-stream
      Content-Length: 25
      
      тестовая текстовая строка
      PATCH / HTTP/1.1
      Host: localhost:8001
      Content-Type: application/octet-stream
      Content-Length: 25
      
      тестовая текстовая строка
    • Код/Результат:

      $binaryContent = $REQUEST->get('binary', Request::FILE);
      
      echo $binaryContent;
      тестовая текстовая строка
    • Запросы с файлом:

      POST / HTTP/1.1
      Host: localhost:8001
      Content-Type: application/octet-stream
      Content-Length: 20
      
      "<file contents here>"
      PUT / HTTP/1.1
      Host: localhost:8001
      Content-Type: application/octet-stream
      Content-Length: 20
      
      "<file contents here>"
      PATCH / HTTP/1.1
      Host: localhost:8001
      Content-Type: application/octet-stream
      Content-Length: 20
      
      "<file contents here>"
    • Код/Результат:

      $binaryFile = $REQUEST->get('binary', Request::FILE);
      
      echo $binaryFile;
      (binary)

Ограничения и ошибки разбора тела запроса

  • multipart/form-data поддерживается только для POST-запросов. Для PUT, PATCH и DELETE этот тип содержимого не поддерживается и при обращении с этими HTTP-методами конструктор Request выбросит исключение UnexpectedValueException с текстом Unsupported Media Type и кодом 415.
  • При обработке multipart/form-data элементы $_FILES с ошибками отбрасываются, не попадают в набор Request::FILE и не возвращаются в $REQUEST->get($key, Request::FILE).
  • Если тело запроса с заголовком Content-Type: application/json содержит невалидный JSON, конструктор Request выбросит исключение UnexpectedValueException с текстом Invalid JSON и кодом 400.
  • Если тип содержимого не поддерживается для текущего HTTP-метода, конструктор Request выбрасывает исключение UnexpectedValueException с текстом Unsupported Media Type и кодом 415.
  • application/octet-stream поддерживается только для POST, PUT и PATCH HTTP-методов. Данные сохраняются в наборе Request::FILE по ключу binary, который можно получить методом $REQUEST->get('binary', Request::FILE). Для DELETE этот тип содержимого не поддерживается и при обращении с этим HTTP-методом конструктор Request выбрасывает исключение UnexpectedValueException с текстом Unsupported Media Type и кодом 415.

Работа с массивами

Получение массива параметров

Если в метод $REQUEST->get($key = null, $method = Request::GET) не передать $key или передать его как null, то он вернёт весь набор параметров в виде массива.

  • Запрос:

    POST / HTTP/1.1
    Host: localhost:8001
    Content-Type: application/json
    Content-Length: 65
    
    {
      "data": {
        "name": "App",
        "email": "app@mail.ru"
      }
    }
  • Код/Результат:

    $payload = $REQUEST->get(null, Request::POST);
    
    print_r($payload);
    Array
    (
      [data] => Array
        (
          [name] => App
          [email] => app@mail.ru
        )
    )

Установка параметров запроса

Метод $REQUEST->set($key, $value, $method) позволяет программно записать значение в нужный набор данных запроса.

Код/Результат:

$REQUEST->set('index', 1, Request::GET);
$REQUEST->set('index', 2, Request::POST);
$REQUEST->set('index', 3, Request::PUT);
$REQUEST->set('index', 4, Request::PATCH);
$REQUEST->set('index', 5, Request::DELETE);
$REQUEST->set('index', 6, Request::FILE);

$getIndex = $REQUEST->get('index', Request::GET);
$postIndex = $REQUEST->get('index', Request::POST);
$putIndex = $REQUEST->get('index', Request::PUT);
$patchIndex = $REQUEST->get('index', Request::PATCH);
$deleteIndex = $REQUEST->get('index', Request::DELETE);
$fileIndex = $REQUEST->get('index', Request::FILE);

echo sprintf(
    "getIndex %d\npostIndex %d\nputIndex %d\npatchIndex %d\ndeleteIndex %d\nfileIndex %d",
    $getIndex, $postIndex, $putIndex, $patchIndex, $deleteIndex, $fileIndex
);
getIndex 1
postIndex 2
putIndex 3
patchIndex 4
deleteIndex 5
fileIndex 6