web-dev-qa-db-ja.com

file_get_contents( 'php:// input')は常に空の文字列を返します

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データを読むためにそれを手に入れていません。私は何を間違えていますか?

16
Igor

ウェブ上の他の場所に記載php://inputリクエストがリダイレクトされた場合、コンテンツは通過しません。 Webサーバーには、wwwで始まるURLからwwwを含まないURLへのリダイレクト、またはHTTPを使用するURLからHTTPSを使用するURLへのリダイレクトがある場合があります。 Webサーバーのログを確認してこれを確認し、Webサービスを呼び出すときにリダイレクトを回避するように適切に対応してください。

12

最初に、私はこのコードを実行することができ、うまくいきました:

_--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設定を確認してください。

  1. 使用したcurl url、urlが実際に機能し、エラーを返さないことを確認してください。
  2. 別のターミナル/コンソールウィンドウを開いて_tail -f /path/to/the/php/log/file_を実行すると、これらのphp呼び出しの出力を実際に確認できます。
  3. 多くの場合、人々はこのエラーを受け取ります:file_get_contents(file://input): failed to open stream: no suitable wrapper could be foundは、「file:// input」文字列のタイプミスか、PHPで_allow_url_fopen_が無効になっていることを示します(不明な場合は#5を参照)
  4. コードが正しいことを確認してください。それにより、誤った引数やものを入力していないことを確認します。netbeansで必ずしも下線が引かれていないもの。
  5. _file_get_contents_は、PHPの設定で_allow_url_fopen_がtrueに設定されている場合にのみ機能します。これはphp.iniで設定されているものですが、設定を変更することもできます。次のコードの行に沿って他のコードの前に何かを書くことで実行します。

    _ini_set("allow_url_fopen", true);
    _
8
Kristian

私はこのコードでヘッダーファイルを書きました:

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"];
2
Radon8472

私もこのエラーを受け取っていました。私の解決策は、データ形式をrawに変更することです。

私はそれを php doc から入手します

:php://input is not available with enctype="multipart/form-data".
2
Timtcng.sen

正しい関数呼び出しは次のとおりです。

file_get_contents("php://input");

php:inputが存在しないというエラーメッセージが表示されるはずです...

いずれの場合でも、PUTは、サーバーがサポートしていると仮定して、サーバーにファイルをアップロードすることを目的としています。通常、コンテンツに適したContent-TypeヘッダーとともにPOSTを使用します。

1

Windowsでは、「単一の「二重」引用符」の組み合わせは機能しないようです。 JSONデータの引用符にエスケープを使用します(以下を参照)。

curl -X PUT -d "{\"address\":\"Sunset Boulevard\"}" http://localhost/clients/ryan
1
sambha

必要に応じて編集

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;
}
0

同じ問題がありました。最終的に、問題はクライアント側でjsonオブジェクトを文字列化しないことであることがわかりました(以前はnodejsサーバーを使用していたので問題ありませんでした)。それをやったら、通常のパラメーターとして(jsonとしてではなく)$ _POSTのデータを受け取りました。

0
Shlomo

問題が見えます

これを回避するには、リクエストURLの最後にfilename.phpを追加するか、.htaccessファイルのサーバールールを書き換える必要があります。

curl -i -X PUT -d '{"address":"Sunset Boulevard"}' http://localhost/clients/ryan/{filename.php}

{filename.php}を適切なファイル名に置き換えます。 :)

0
Mandan Sharma

httpから_http://_または_.php_から_/_へのリダイレクトが行われていないことを確認してください

file_get_contents(php://input)は、リダイレクトを介して本文コンテンツを渡しません(そうするようにWebサーバーを構成することは可能ですが)。

リダイレクトをチェックする簡単な方法の1つは、curlでURLをチェックすることです。コマンドラインで:_curl -IL http://example.com/api_

0
billrichards