File_get_contents ('php://input') всегда возвращает пустую строку

Я создаю PHP RESTful API, следуя этому учебнику. Следующая функция, которая должна возвращать данные, отправленные с запросом при использовании метода put, возвращает null каждый раз:

file_get_contents('php://input').

Я даже скачал и протестировал полный пример кода в учебнике, и он по-прежнему возвращает null.

Я использую cURL и следующую команду для тестирования метода put:

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

Я потратил дни на это и до сих пор не получил его, чтобы прочитать данные json. Что я делаю неправильно?

Ответ 1

Как отмечалось в другом месте в Интернете, php://input контент php://input не проходит, если запрос перенаправлен. Возможно, ваш веб-сервер имеет перенаправление с URL-адреса, начинающегося с www, на URL-адрес без www или с URL-адресов, использующих HTTP, на URL-адреса, использующие HTTPS. Проверьте журналы своего веб-сервера, чтобы убедиться в этом, и действуйте соответствующим образом, чтобы избежать перенаправления при совершении вызовов веб-службе.

Ответ 2

Во-первых, я смог запустить этот код, и он работал нормально:

--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:

  • URL-адрес curl, который вы использовали, убедитесь, что URL-адрес фактически работает и не возвращает ошибки.
  • откройте еще одно окно терминала/консоли и запустите 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", либо тот факт, что allow_url_fopen отключен в php (см. № 5, если не уверен)
  • убедитесь, что ваш код правильный, и я имею в виду, что вы не вводите неверные аргументы и вещи... вещи, которые не обязательно подчеркиваются в netbeans.
  • помните, file_get_contents работает только тогда, когда allow_url_fopen установлено в true в ваших настройках PHP. это то, что установлено в php.ini, но вы также можете изменить настройки во время выполнения, написав что-то вдоль строк следующего кода перед другим кодом:

    ini_set("allow_url_fopen", true);
    

Ответ 3

Я написал заголовочный файл с этим кодом:

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-Length. При получении действительного JSON он создал глобальный массив $_POST_JSON.

Таким образом, вы можете работать с вашим JSON-содержимым так же, как вы это делаете, с значениями POST, закодированными в URL-адресе.

Пример:

 echo $_POST_JSON["address"];
 // or
 echo $_REQUEST["address"];

Ответ 4

У меня тоже была эта ошибка, мое решение - изменить формат данных на raw.

Я получаю его от php doc, где он говорит

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

Ответ 5

Правильный вызов функции:

file_get_contents("php://input");

Вы должны получить сообщение об ошибке, говорящее, что php:input не существует...

В любом случае PUT предназначен для загрузки файлов на сервер, если сервер поддерживает его. Обычно вы используете POST с заголовком Content-Type, соответствующим содержимому.

Ответ 6

В Windows комбинация "одиночных" двойных "кавычек" не работает. Используйте escape для кавычек в ваших json-данных (как показано ниже), и он должен работать

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

Ответ 7

Я вижу проблему,

Вам нужно добавить filename.php в конце URL-адреса запроса или переписать правила сервера в файле .htaccess, чтобы обойти это.

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

замените {filename.php} на соответствующее имя файла. :)

Ответ 8

У меня такая же проблема. В конце концов, я обнаружил, что проблема заключалась в том, что на стороне клиента я не разбил на строку объект json (ранее я использовал сервер nodejs, и все было в порядке). Как только я это сделал, я получил данные в $ _POST (а не в формате json) как обычные параметры.

Ответ 9

Отредактируйте как хотите

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

Ответ 10

Убедитесь, что не происходит переадресация (например, с http на http:// или с .php на /)

file_get_contents(php://input) не передает содержимое тела через перенаправления (хотя я думаю, что можно настроить веб-сервер для этого).

Один быстрый способ проверить наличие перенаправлений - проверить URL с помощью curl. В командной строке: curl -IL http://example.com/api

Ответ 11

для меня эта проблема началась внезапно.
Я установил SSL-сертификат.
когда я проверил код ответа, он показал мне 301, затем я понял и изменил
http://
на
https://
и получил весь запрос обратно с file_get_contents ('php://input').

в вашем примере вызов curl:
поставить s после http, как показано ниже:
curl -i -X PUT -d '{"address":"Sunset Boulevard"}' https://localhost/clients/ryan