Статьи

HTTP глаголы в PHP


Хотя PHP способен выполнять HTTP-запросы к внешним серверам любым методом, либо с помощью расширения HTTP, либо напрямую открывая потоки, поддержка различных GET, POST, PUT и других глаголов на принимающей стороне HTTP-запросов немного больше сложно.

История вопроса

Спецификация HTTP 1.0 (
RFC 1945 ) официально определяла только методы GET, HEAD и POST, оставляя открытой возможность добавления методов расширения:

Method        = "GET"                    ; Section 8.1
| "HEAD" ; Section 8.2
| "POST" ; Section 8.3
| extension-method

Спецификация HTTP 1.1 (как и его последнее воплощение 1999
RFC 2616 ) явно определяет другие методы:

Method         = "OPTIONS"                ; Section 9.2
| "GET" ; Section 9.3
| "HEAD" ; Section 9.4
| "POST" ; Section 9.5
| "PUT" ; Section 9.6
| "DELETE" ; Section 9.7
| "TRACE" ; Section 9.8
| "CONNECT" ; Section 9.9
| extension-method

Из этих методов наиболее интересными из-за их использования в
приложениях
RESTful являются GET, POST, PUT и DELETE:

  • GET — это безопасный идемпотентный метод, который используется для извлечения ресурса.
  • В настоящее время POST считается универсальным методом, но его целью является определение подчиненного ресурса для текущего. Например, публикация на ресурсе блога может создать новый пост.
  • PUT — это аналог GET, используемый для отправки ресурса на HTTP-сервер.
  • DELETE — это аналог GET, используемый, конечно, для удаления определенного ресурса.


Поддержка клиентов

GET и POST — это набор запросов, направленных к приложениям PHP. Они обычно генерируются непосредственно браузером. Запрос GET генерируется ссылкой или формой с указанным атрибутом метода, установленным как
get . Вместо этого запрос POST обычно можно получить
в собственном HTML 4 только с формой, которая может также
содержать атрибут enctype для установки
заголовка Content-Type запроса (обычно используется для загрузки файлов методом POST.)

Браузеры часто ограничивают свою поддержку HTTP-запроса этими двумя, поскольку спецификация HTML не определяет стандартное средство для генерации других типов запросов на стороне клиента. У нас есть программный способ выполнения асинхронных HTTP-запросов, Javascript, но он также не помогает, поскольку он ограничен возможностями разработчика.

Библиотеки Javascript не налагают конкретных ограничений разрешенных методов: мы можем отправлять запросы GET, POST, PUT или DELETE конечной точке на сервере, но через объект XMLHttpRequest (который является их стандартным внутренним интерфейсом) неподдерживаемые методы будут эмулироваться через перегруженный POST. Это означает, что запрос POST будет создан с дополнительным параметром (который может называться
_method или
_requestType(в зависимости от конкретной библиотеки), которая описывает фактический метод, используемый в клиенте. Вы можете поддерживать семантику запроса в клиентском коде, и, возможно, в будущем будет доступна встроенная поддержка запросов PUT и DELETE.

Есть способы сделать реальный запрос PUT или DELETE, и они обычно требуют более сложной инфраструктуры на клиенте, такой как Java-апплеты или нестандартный Javascript (который не поддерживается в большинстве браузеров), или даже не используют браузер как клиент, например, использующий веб-сервис, действующий как клиент другого.

Поддержка сервера

Но как мы можем обнаружить метод HTTP-запроса в сценарии PHP? Для распространенных методов, таких как GET и POST, суперглобальные массивы $ _GET и $ _POST всегда доступны и содержат параметры запроса. Возможно, вы захотите обернуть их объектно-ориентированным интерфейсом и обратите внимание, что в случае загрузки файлов через POST вы также должны посмотреть на суперглобальный массив $ _FILES.

Для других методов первое, что нужно сделать, — настроить ваш веб-сервер с помощью директивы, которая направляет все запросы PUT в одну динамическую точку входа. В случае Apache это описано в руководстве по PHP как:

Script PUT /put.php

Указанный скрипт просто должен прочитать из стандартного ввода запрос PUT:

$putdata = fopen("php://input", "r");

file_get_contents () не будет работать здесь; добро пожаловать в мир
CGI ! 🙂

В
ручных и пользовательских комментариях также являются ценным ресурсом для распространенных ошибок при реализации этого типа конечных точек.

Что касается запросов DELETE, то та же конфигурация действительна для направления запросов в одну точку входа. Затем необходимо определить правильные переменные среды, которые могут различаться в зависимости от вашего HTTP-сервера. К счастью, фреймворки PHP выполняют
большую часть работы , и вы можете программно реализовывать различные варианты поведения в зависимости от типа запроса.