Подтвердить что ты не робот

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.

4b9b3361

Ответ 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