PHP получает тело запроса PUT

В настоящее время я разрабатываю Restful Json-API в PHP. Я хочу отправить PUT-Request в items/:id чтобы обновить запись. Данные будут переданы как application/json .

Я хочу вызвать API с помощью

 curl -H "Content-Type: application/json" -X PUT -d '{"example" : "data"}' "http://localhost/items/someid" 

На стороне сервера я не могу получить тело запроса. Я пытался

 file_get_contents("php://input"); 

но это возвращает пустую строку. Также комбинация fopen() / fread() не работает.

При вызове через POST все работает отлично, я отлично читаю json на стороне сервера. Но API больше не Restful. У кого-нибудь есть решение для этого? Есть ли другой способ отправить и получить Json?

Кстати, я разрабатываю API с помощью Slim Framework .

php://input доступен только один раз для запросов PUT:

Примечание. Поток, открытый с помощью ввода php: //, может быть прочитан только один раз; поток не поддерживает операции поиска. Однако, в зависимости от реализации SAPI, может быть возможно открыть другой поток ввода php: // и перезапустить чтение. Это возможно только в том случае, если данные тела запроса сохранены. Как правило, это относится к запросам POST, но не к другим методам запроса, таким как PUT или PROPFIND.

http://php.net/manual/en/wrappers.php.php

Структура Slim уже считывает данные по запросу. Возьмите данные из объекта Request, в который он был прочитан.

На стороне сервера я не могу получить тело запроса. Я попробовал file_get_contents ("php: // input");

Вы можете использовать только file_get_contents( 'php://input', 'r' ); один раз за запрос. Извлечение значений также приведет к усечению значений, поэтому, если вы вызовете его дважды, он вернет пустую строку. Объект запроса Slim содержит значения, которые вам нужны, поэтому:

 <?php $app = new Slim( ); $app->put( '/items/someid', function () use ( $app ) { echo $app->request( )->put( 'example' ); // should display "data". }); 

В примере из руководства PHP используется fopen для доступа к входу php: // в режиме чтения. Вы пытались сделать это именно так?

EDIT: Страница руководства для PHP: // говорит некоторые вещи, которые, кажется, предполагают, что данные PUT могут быть недоступны в некоторых случаях!

Примечание. Поток, открытый с помощью ввода php: //, может быть прочитан только один раз; поток не поддерживает операции поиска. Однако, в зависимости от реализации SAPI, может быть возможно открыть другой поток ввода php: // и перезапустить чтение. Это возможно только в том случае, если данные тела запроса сохранены. Как правило, это относится к запросам POST, но не к другим методам запроса, таким как PUT или PROPFIND.

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

На днях я читал документацию по структуре SLIM, и он сказал, что некоторые браузеры имеют проблемы с PUT и DELETE.

Выдержка:

К сожалению, современные браузеры не предоставляют встроенную поддержку запросов PUT. Чтобы обойти это ограничение, убедитесь, что ваш метод HTML-формы является «post», а затем добавьте параметр переопределения метода в вашу HTML-форму следующим образом:

 <form action="/books/1" method="post"> ... other form fields here... <input type="hidden" name="_METHOD" value="PUT"/> <input type="submit" value="Update Book"/> </form> 

Источник: http://www.slimframework.com/documentation/stable