2012-03-13 10 views
12

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

Я хочу, чтобы вызвать 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.

+0

Вы попробовали fopen ("php: // input", "r")? – sethcall

+0

Да, не работает. – aladin

+1

Удивительно, что вы используете тонкий. Надеюсь, у вас хороший опыт. Мне очень понравилось создание SLIM restful api – Jake

ответ

13

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

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

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

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

+4

Большое спасибо, это решило мою проблему. Я могу получить необработанные данные с помощью $ app-> request-> getBody(); а затем выполните json_decode. Я не знал об этом методе, поскольку он не содержится в документации. – aladin

+0

+1 Это была моя проблема с использованием restTonic PHP framework. Эта переменная $ this-> request-> уже содержала тело PUT. Я прочитал вход php: // в моем обработчике POST и не мог понять, почему обработчик PUT не мог использовать тот же метод для обработки своего тела. – Neek

-1

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

Выдержки:

К сожалению, современные браузеры не обеспечивают нативную поддержку запросов PUT. Чтобы обойти это ограничение, обеспечить метод вашего HTML-форм является «пост», а затем добавить параметр метода переопределения в вашей 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

+0

OP использует Curl для выполнения операции HTTP PUT. – GordonM

+0

Я немного новичок в этом, но cURL просто отказывается от проблемы с браузером? Что делать, если он выполняет запрос curl через PHP, и это эквивалент командной строки? (Я не говорю, что он есть, я говорю, что преимущество в командной строке cURL все равно существует) – Jake

+0

@ Jake: да, с использованием cURL отказывается от проблемы с браузером. Ни один браузер не задействован так, как он звонит в службу. – Crontab

0

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

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

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

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

1

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

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

<?php 
$app = new Slim(); 

$app->put('/items/someid', function() use ($app) { 
    echo $app->request()->put('example'); // should display "data". 
}); 
+1

Это верно для данных с кодировкой url, но не для сырого json. если я отправляю кодировку url данных, я могу получить к ней доступ через объект запроса Slim. не работает для json hard. – aladin

+0

Вопрос остается; вы можете читать только с php: // input * once *, и Slim уже это сделал. Вам нужно будет использовать объект запроса Slim для получения ваших значений. –

+1

По-видимому, Slim Framework считывает тело запроса при построении, поэтому php: // вход уже удален. спасибо! – aladin

Смежные вопросы