PHP «php: // input» против $ _POST

175

Мне было предложено использовать метод php://input вместо $_POST при взаимодействии с запросами Ajax от JQuery. То, что я не понимаю, - это преимущества использования этого против глобального метода $_POST или $_GET.

  • 0
    Раньше я использовал «хаки» для получения вызовов ajax на стороне PHP, прежде чем наткнуться на этот пост и прочитать его удивительные ответы! Я надеюсь, что для других людей, имеющих такую же проблему в будущем, поисковые системы тоже прочтут мой комментарий! :)
Теги:
input

4 ответа

373
Лучший ответ

Причина в том, что php://input возвращает все необработанные данные после HTTP-заголовков запроса независимо от типа содержимого.

Суперглобальный PHP $_POST, только предполагается обернуть данные, которые либо

  • application/x-www-form-urlencoded (стандартный тип содержимого для простых форм-сообщений) или
  • multipart/form-data-encoded (в основном используется для загрузки файлов)

Это потому, что это единственные типы контента, которые должны поддерживаться агентами пользователей. Таким образом, сервер и PHP традиционно не ожидают получения какого-либо другого типа контента (что не означает, что они не могут).

Итак, если вы просто POST добрый старый HTML form, запрос выглядит примерно так:

POST /page.php HTTP/1.1

key1=value1&key2=value2&key3=value3

Но если вы много работаете с Ajax, этот probaby также включает обмен более сложными данными с типами (string, int, bool) и структурами (массивами, объектами), поэтому в большинстве случаев JSON - лучший выбор. Но запрос с полезной нагрузкой JSON будет выглядеть примерно так:

POST /page.php HTTP/1.1

{"key1":"value1","key2":"value2","key3":"value3"}

Теперь контент будет application/json (или, по крайней мере, ни один из вышеперечисленных), поэтому PHP $_POST -wrapper не знает, как справиться с этим (пока).

Данные все еще существуют, вы просто не можете получить к нему доступ через оболочку. Поэтому вам нужно получить его в необработанном формате с помощью file_get_contents('php://input') (пока это не multipart/form-data -encoded).

Также вы можете получить доступ к XML-данным или любому другому нестандартному типу содержимого.

  • 36
    +1 за «Это также, как вы бы получили доступ к XML-данным или любому другому нестандартному типу контента»
  • 0
    @Quasdank Я отправляю JSON из приложения Android на сервер php xampp в облаке ( stackoverflow.com/questions/36558261/… ), но не могу заставить его работать, когда я пытаюсь file_get_contents ('php: // input'), который просто возвращает строку (0). Раньше это работало на моей локальной машине, но не работало, когда я развертывал его в облаке. Не могли бы вы мне помочь, пожалуйста?
Показать ещё 2 комментария
38

php://input может предоставить вам необработанные байты данных. Это полезно, если данные POSTed представляют собой кодированную структуру JSON, что часто бывает в случае запроса AJAX POST.

Здесь функция, которая выполняет только это:

  /**
   * Returns the JSON encoded POST data, if any, as an object.
   * 
   * @return Object|null
   */
  private function retrieveJsonPostData()
  {
    // get the raw POST data
    $rawData = file_get_contents("php://input");

    // this returns null if not valid json
    return json_decode($rawData);
  }

Массив $_POST более полезен, когда вы обрабатываете данные о ключевом значении из формы, представленной традиционным POST. Это работает только в том случае, если данные POSTed находятся в распознанном формате, обычно application/x-www-form-urlencoded (подробнее см. http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4).

  • 5
    Стоит отметить, что если вы передадите true в качестве второго параметра в json_decode , он вернет ассоциативный массив.
23

Если данные сообщения неверны, $_POST не будет содержать ничего. Тем не менее, вход php://будет иметь неверную строку.

Например, есть некоторые приложения ajax, которые не образуют правильную последовательность после ввода ключа для загрузки файла и просто выгружают весь файл в виде пост-данных без имен переменных или чего-либо еще. $ _POST будет пустым, пустым будет $_FILES, а вход php://будет содержать точный файл, написанный как строка.

0

Простой пример того, как его использовать

 <?php  
     if(!isset($_POST) || empty($_POST)) { 
     ?> 
        <form name="form1" method="post" action=""> 
          <input type="text" name="textfield"><br /> 
          <input type="submit" name="Submit" value="submit"> 
        </form> 
   <?php  
        } else { 
        $example = file_get_contents("php://input");
        echo $example;  }  
   ?>

Ещё вопросы

Сообщество Overcoder
Наверх
Меню