PHP RESTful API、次の this チュートリアルを作成しています。次の関数は、 'put'メソッドが使用されたときにリクエストと共に送信されたデータを返します。 、毎回nullを返します。
file_get_contents('php://input')
。
チュートリアルの完全なコード例をダウンロードしてテストしても、まだnullが返されます。
「put」メソッドをテストするために、cURLと次のコマンドを使用しています。
curl -i -X PUT -d '{"address":"Sunset Boulevard"}' http://localhost/clients/ryan
。
私はこれに何日も費やしましたが、まだjsonデータを読むためにそれを手に入れていません。私は何を間違えていますか?
ウェブ上の他の場所に記載 、php://input
リクエストがリダイレクトされた場合、コンテンツは通過しません。 Webサーバーには、wwwで始まるURLからwwwを含まないURLへのリダイレクト、またはHTTPを使用するURLからHTTPSを使用するURLへのリダイレクトがある場合があります。 Webサーバーのログを確認してこれを確認し、Webサービスを呼び出すときにリダイレクトを回避するように適切に対応してください。
最初に、私はこのコードを実行することができ、うまくいきました:
_--Terminal---------
//I ran this curl request against my own php file:
curl -i -X PUT -d '{"address":"Sunset Boulevard"}' http://localhost/test.php
--PHP--------------
//get the data
$json = file_get_contents("php://input");
//convert the string of data to an array
$data = json_decode($json, true);
//output the array in the response of the curl request
print_r($data);
_
それでもうまくいかない場合は、コンソールでエラーとPHP設定を確認してください。
tail -f /path/to/the/php/log/file
_を実行すると、これらのphp呼び出しの出力を実際に確認できます。file_get_contents(file://input): failed to open stream: no suitable wrapper could be found
は、「file:// input」文字列のタイプミスか、PHPで_allow_url_fopen
_が無効になっていることを示します(不明な場合は#5を参照)_file_get_contents
_は、PHPの設定で_allow_url_fopen
_がtrueに設定されている場合にのみ機能します。これはphp.iniで設定されているものですが、設定を変更することもできます。次のコードの行に沿って他のコードの前に何かを書くことで実行します。
_ini_set("allow_url_fopen", true);
_
私はこのコードでヘッダーファイルを書きました:
if($_SERVER["REQUEST_METHOD"] == "POST" && $_SERVER["CONTENT_TYPE"] == "application/json")
{
$data = file_get_contents("php://input", false, stream_context_get_default(), 0, $_SERVER["CONTENT_LENGTH"]);
global $_POST_JSON;
$_POST_JSON = json_decode($_REQUEST["JSON_RAW"],true);
// merge JSON-Content to $_REQUEST
if(is_array($_POST_JSON)) $_REQUEST = $_POST_JSON+$_REQUEST;
}
正しいcontent-typeをチェックし、Content-Lengthヘッダーで指定されているように、できるだけ多くの投稿入力を読み取ります。有効なJSONを受信すると、グローバル配列$ _POST_JSONを作成しました。
したがって、url-encoded POST values。で行うのと同様に、JSON-Contentで作業できます。
例:
echo $_POST_JSON["address"];
// or
echo $_REQUEST["address"];
私もこのエラーを受け取っていました。私の解決策は、データ形式をrawに変更することです。
私はそれを php doc から入手します
:php://input is not available with enctype="multipart/form-data".
正しい関数呼び出しは次のとおりです。
file_get_contents("php://input");
php:input
が存在しないというエラーメッセージが表示されるはずです...
いずれの場合でも、PUT
は、サーバーがサポートしていると仮定して、サーバーにファイルをアップロードすることを目的としています。通常、コンテンツに適したContent-Type
ヘッダーとともにPOST
を使用します。
Windowsでは、「単一の「二重」引用符」の組み合わせは機能しないようです。 JSONデータの引用符にエスケープを使用します(以下を参照)。
curl -X PUT -d "{\"address\":\"Sunset Boulevard\"}" http://localhost/clients/ryan
必要に応じて編集
function getPostObject() {
$str = file_get_contents('php://input');
$std = json_decode($str);
if ($std === null) {
$std = new stdClass();
$array = explode('&', $str);
foreach ($array as $parm) {
$parts = explode('=', $parm);
if(sizeof($parts) != 2){
continue;
}
$key = $parts[0];
$value = $parts[1];
if ($key === NULL) {
continue;
}
if (is_string($key)) {
$key = urldecode($key);
} else {
continue;
}
if (is_bool($value)) {
$value = boolval($value);
} else if (is_numeric($value)) {
$value += 0;
} else if (is_string($value)) {
if (empty($value)) {
$value = null;
} else {
$lower = strtolower($value);
if ($lower === 'true') {
$value = true;
} else if ($lower === 'false') {
$value = false;
} else if ($lower === 'null') {
$value = null;
} else {
$value = urldecode($value);
}
}
} else if (is_array($value)) {
// value is an array
} else if (is_object($value)) {
// value is an object
}
$std->$key = $value;
}
// length of post array
//$std->length = sizeof($array);
}
return $std;
}
同じ問題がありました。最終的に、問題はクライアント側でjsonオブジェクトを文字列化しないことであることがわかりました(以前はnodejsサーバーを使用していたので問題ありませんでした)。それをやったら、通常のパラメーターとして(jsonとしてではなく)$ _POSTのデータを受け取りました。
問題が見えます
これを回避するには、リクエストURLの最後にfilename.phpを追加するか、.htaccessファイルのサーバールールを書き換える必要があります。
curl -i -X PUT -d '{"address":"Sunset Boulevard"}' http://localhost/clients/ryan/{filename.php}
{filename.php}を適切なファイル名に置き換えます。 :)
http
から_http://
_または_.php
_から_/
_へのリダイレクトが行われていないことを確認してください
file_get_contents(php://input)
は、リダイレクトを介して本文コンテンツを渡しません(そうするようにWebサーバーを構成することは可能ですが)。
リダイレクトをチェックする簡単な方法の1つは、curlでURLをチェックすることです。コマンドラインで:_curl -IL http://example.com/api
_