$_POST, $HTTP_RAW_POST_DATA, php://input usage comparison

php://input Definition: A read-only stream with access to the requested raw data

php://input usage: read the value of the specified length in the http entity body, the length is specified by Content-Length


HTTP_RAW_POST_DATA

Official documentation explains: Native POST data . It needs to be turned on through php.ini. After turning on, the post data can be obtained through the global variable $GLOBALS['HTTP_RAW_POST_DATA'].

  • You need to set the value in php.ini to  always_populate_raw_post_data On to take effect

  • cannot be used with enctype="multipart/form-data"

  • This global variable has been removed in PHP7 and replaced with php://input

  • Requires more memory than php://input

php://input

php://input  accesses individual input/output streams . Allows access to PHP's input and output streams, standard input and output, and error descriptors, in-memory, disk-backed temporary file streams, and filters that can manipulate other read and write file resources.

  • Does not require any special php.ini settings

  • cannot be used with enctype="multipart/form-data"

  • Data acquisition method: $data = file_get_contents("php://input");

$_POST

It can be seen as the data after filtering and formatting $HTTP_RAW_POST_DATA. The recognized data type is the default data type application/x-www.form-urlencoded recognized by PHP

  • Unable to parse content of non-application/x-www.form-urlencoded data types such as text/xml, application/json, etc.

  • Validated cannot be used with enctype="text/plain"   
  • Validated for use with enctype="multipart/form-data"

Summary and Notes

  • In the case of POST requests, it is better to use php://input instead of $HTTP_RAW_POST_DATA because it does not depend on specific php.ini directives. Moreover, in this case $HTTP_RAW_POST_DATA is not populated by default, which requires less memory than activating always_populate_raw_post_data.

  • Generally, when the GET method submits data, the http request entity body part is empty. 
  • Only when the Coentent-Type is multipart/form-data, PHP will not fill in the corresponding data in the http request packet into php://input, otherwise it will. The length to be filled in, specified by Coentent-Length. 
  • When the Content-Type type is not recognized by PHP, it will fill the corresponding data in the http request packet into the variable $HTTP_RAW_POST_DATA 
  • Only when the Coentent-Type value is application/x-www-data-urlencoded and multipart/form-data, PHP will fill the corresponding data in the http request packet into the global variable $_POST 
  • Only when the Content-Type is application/x-www-data-urlencoded, the php://input data is consistent with the $_POST data.
  • PHP will fill the query_path part of the PATH field into the global variable $_GET. Normally, the http request submitted by the GET method has an empty body.

example

 1.php can receive xml data with file_get_contents("php://input") or $HTTP_RAW_POST_DATA
 such as:

  getXML.php;//Receive XML address

<?php
      $xml  '<xml-->xmldata' ; //要发送的xml
      $url  'http://localhost/test/getXML.php' ;//接收XML地址
      $header  'Content-type: text/xml' ; //定义content-type为xml
      $ch  = curl_init();  //初始化curl
      curl_setopt( $ch , CURLOPT_URL,  $url ); //设置链接
      curl_setopt( $ch , CURLOPT_RETURNTRANSFER, 1); //设置是否返回信息
      curl_setopt( $ch , CURLOPT_HTTPHEADER,  $header ); //设置HTTP头
      curl_setopt( $ch , CURLOPT_POST, 1); //设置为POST方式
      curl_setopt( $ch , CURLOPT_POSTFIELDS,  $xml ); //POST数据
      $response  = curl_exec( $ch ); //接收返回信息
      if (curl_errno( $ch )){ //出错则显示错误信息
      print  curl_error( $ch );
      }
      curl_close( $ch );  //关闭curl链接
      echo  $response ; //显示返回信息
?>
 2. A small program that uploads pictures to the server from a mobile phone
   
<?php
      //@file phpinput_post.php
      $data = file_get_contents ( 'btn.png' );
      $http_entity_body  $data ;
      $http_entity_type  'application/x-www-form-urlencoded' ;
      $http_entity_length  strlen ( $http_entity_body );
      $host  '127.0.0.1' ;
      $port  = 80;
      $path  '/image.php' ;
      $fp  fsockopen ( $host $port $error_no $error_desc , 30);
      if  ( $fp ){
         fputs ( $fp "POST {$path} HTTP/1.1\r\n" );
         fputs ( $fp "Host: {$host}\r\n" );
         fputs ( $fp "Content-Type: {$http_entity_type}\r\n" );
         fputs ( $fp "Content-Length: {$http_entity_length}\r\n" );
         fputs ( $fp "Connection: close\r\n\r\n" );
         fputs ( $fp $http_entity_body  "\r\n\r\n" );
         while  (! feof ( $fp )) {
          $d  .=  fgets ( $fp , 4096);
         }
         fclose( $fp );
         echo  $d ;
      }
?>

3. Receive documents
  
<?php
       /**
        *Recieve image data
       **/   
       error_reporting (E_ALL);
      function  get_contents() {   
         $xmlstr file_get_contents ( "php://input" );
         $filename =time(). '.png' ;
         if ( file_put_contents ( $filename , $xmlstr )){
            echo  'success' ;
          } else {
            echo  'failed' ;
          }
        }
        get_contents();
?>

 4. Get the original HTTP request
  
    /**
      * 获取HTTP请求原文
      * @return string
      */
     function  get_http_raw() {
        $raw  '' ;
        // (1) 请求行
        $raw  .=  $_SERVER [ 'REQUEST_METHOD' ]. ' ' . $_SERVER [ 'REQUEST_URI' ]. ' ' . $_SERVER [ 'SERVER_PROTOCOL' ]. "\r\n" ;
        // (2) 请求Headers
        foreach ( $_SERVER  as  $key  =>  $value ) {
          if ( substr ( $key , 0, 5) ===  'HTTP_' ) {
             $key  substr ( $key , 5);
             $key  str_replace ( '_' '-' $key );
             $raw  .=  $key . ': ' . $value . "\r\n" ;
           }
         }
        // (3) 空行
        $raw  .=  "\r\n" ;
        // (4) 请求Body
        $raw  .=  file_get_contents ( 'php://input' );
        return  $raw ;
     }

Related Posts