2012-03-13 8 views
12

私は現在、PHPでRestful Json-APIを開発中です。 items/:idにPUT-Requestを送ってレコードを更新したいと思います。データはapplication/jsonとして転送されます。私は、サーバー側でPHPはPUTリクエストボディを取得します

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

でAPIを呼び出したい

、私はインクルードは、リクエストボディを取得することはできませんよ。試しました

file_get_contents("php://input"); 

しかし、これは空の文字列を返します。 fopen()/fread()の組み合わせも動作しません。

POST経由で呼び出すと、すべて正常に動作し、サーバー側でjsonを完全に読み取ることができます。しかし、APIはもはや安静ではありません。誰にもこれに対する解決策がありますか? Jsonを送受信する別の方法はありますか?

btw、私はSlim FrameworkでAPIを開発しています。

+0

fopen( "php:// input"、 "r")を試しましたか? – sethcall

+0

はい、うまくいきませんでした。 – aladin

+1

あなたはスリムを使用していると素晴らしいです。あなたが良い経験をしていることを願っています。私は本当にSLIMの安らかな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フレームワークを使用して私の問題でした。 $ this-> request-> data変数はすでにPUT本体を保持していました。私はPOSTハンドラでphp://の入力を読んでいたので、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はブラウザの問題を無視していますか?彼がPHP経由でカールリクエストをしていて、それがコマンドラインと同等のものだとしたら? (私は彼が言っているわけではない、私はコマンドラインcURLの利益がまだ存在すると言っている) – Jake

+0

@ジェイク:はい、cURLを使用してブラウザの問題を忘れて。彼がサービスを呼び出す方法はブラウザに関係しません。 – Crontab

0

PHP manualからは、関数fopenを使用しています読み込みモードでphp://入力にアクセスします。代わりにそうしたことがありますか?

編集:manual page for PHP://には、PUTデータが利用できないことがあるようです。

注:php://入力で開かれたストリームは一度しか読み取ることができません。 ストリームはシーク操作をサポートしていません。ただし、 SAPIの実装によっては、別のphp://入力 ストリームを開いて読み込みを再開することができます。これは、要求本体 のデータが保存されている場合にのみ可能です。通常、POST要求の場合は ですが、PUTやPROPFINDなどの他の要求メソッドはありません。

PUT処理に関してどこから離れるのかわかりません。 1つのページは可能であると思われ、もう1つは間違った状況下では機能しないことを暗示しているようです。

1

サーバー側では、リクエストボディを取得できません。私はfile_get_contents( "php:// input")を試しました。

file_get_contents('php://input', 'r');はリクエストごとに1回しか使用できません。値を取得すると値も切り捨てられます.2回呼び出すと、空の文字列が返されます。スリムのリクエストオブジェクトは、そう、あなたが必要とする値が含まれています

<?php 
$app = new Slim(); 

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

これは、URLエンコードされたデータに当てはまりますが、raw jsonでは該当しません。私がエンコードされたデータURLを送ると、私はSlimのリクエストオブジェクト経由でアクセスできます。 json toughではうまくいきません。 – aladin

+0

問題は残ります。あなたはphp:// input * once *からしか読むことができず、Slimはすでにそれを行っています。 Slimのリクエストオブジェクトを使用して値を取得する必要があります。 –

+1

スリムフレームワークは作成時にリクエストボディを読み込むので、php:// inputはすでに削除されています。どうも! – aladin

関連する問題