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?
btw, я разрабатываю API с Slim Framework.
Ответы
Ответ 1
php://input
доступен только один раз для запросов PUT:
Примечание. Поток, открытый с помощью ввода php://, может быть прочитан только один раз; поток не поддерживает операции поиска. Однако, в зависимости от реализации SAPI, может быть возможно открыть другой поток ввода php://и перезапустить чтение. Это возможно только в том случае, если данные тела запроса сохранены. Как правило, это относится к запросам POST, но не к другим методам запроса, таким как PUT или PROPFIND.
http://php.net/manual/en/wrappers.php.php
Структура Slim уже считывает данные по запросу. Возьмите данные из объекта Request, в который он был прочитан.
Ответ 2
На стороне сервера я не могу получить тело запроса. Я попробовал file_get_contents ( "php://input" );
Вы можете использовать только file_get_contents( 'php://input', 'r' );
один раз за запрос. Извлечение значений также приведет к усечению значений, поэтому, если вы вызовете его дважды, он вернет пустую строку. Объект Slim request содержит нужные значения, поэтому:
<?php
$app = new Slim( );
$app->put( '/items/someid', function () use ( $app ) {
echo $app->request( )->put( 'example' ); // should display "data".
});
Ответ 3
В примере из руководства PHP используется fopen для доступа к входу php://в режиме чтения. Вы пытались сделать это именно так?
EDIT: справочная страница для PHP:// говорит о некоторых вещах, которые, по-видимому, предполагают, что данные PUT могут быть недоступны в некоторых случаях!
Примечание. Поток, открытый с помощью ввода php://, может быть прочитан только один раз; поток не поддерживает операции поиска. Однако, в зависимости от SAPI, может быть возможно открыть другой вход php:// поток и перезапуск чтения. Это возможно только в том случае, если тело запроса данные сохранены. Как правило, это относится к запросам POST, но не другие методы запроса, такие как PUT или PROPFIND.
Я не знаю, где это оставит вас в отношении обработки PUT. Кажется, что одна страница говорит, что это возможно, другая, по-видимому, подразумевает, что она не будет работать под неправильным набором обстоятельств.
Ответ 4
Я читал рамочную документацию 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