2014-05-03 7 views
6

Ich bin auf der Suche nach einer Möglichkeit, mit nativen PHP, die rohe HTTP-Anfrage, die mein Skript erhalten, einschließlich der Kopfzeilen und Körper. Wenn ich die PHP-Dokumentation lese, kann ich keine Standardmethode finden, um die rohe Anfrage zu bekommen, ungeachtet der verwendeten HTTP-Methode.Holen Sie sich die rohe Anfrage mit PHP

Zum Beispiel, wenn die Seite test.php angefordert wird, möchte ich wie die vollständige Anfrage erhalten:

GET /test.php HTTP/1.1 
Host:.... 
.... 
.... 

Dasselbe bei POST, HEAD, etc ...

Scheint sehr seltsam, dass es keine Methode gibt, auf den Raw-Anfragepuffer zuzugreifen!

Antwort

10

Wenn Sie über das Handbuch schauen, scheint es nicht einen ungepackten rohen Zugriff auf die Anfrage zu geben, um das zu erreichen, was Sie wollen, also vermute ich, dass Sie aus den $_SERVER Variablen neu aufbauen müssen. Eine schnelle Suche Ich fand diese Klasse, machte ein paar kleine Änderungen, um die GET/HTTP/1.1 zu bekommen, vielleicht finden Sie es für Ihre Bedürfnisse.

<?php 
/** 
* Access the HTTP Request 
* 
* Found on http://www.daniweb.com/web-development/php/code/216846/get-http-request-headers-and-body 
*/ 
class http_request { 

    /** additional HTTP headers not prefixed with HTTP_ in $_SERVER superglobal */ 
    public $add_headers = array('CONTENT_TYPE', 'CONTENT_LENGTH'); 

    /** 
    * Construtor 
    * Retrieve HTTP Body 
    * @param Array Additional Headers to retrieve 
    */ 
    function http_request($add_headers = false) { 

     $this->retrieve_headers($add_headers); 
     $this->body = @file_get_contents('php://input'); 
    } 

    /** 
    * Retrieve the HTTP request headers from the $_SERVER superglobal 
    * @param Array Additional Headers to retrieve 
    */ 
    function retrieve_headers($add_headers = false) { 

     if ($add_headers) { 
      $this->add_headers = array_merge($this->add_headers, $add_headers); 
     } 

     if (isset($_SERVER['HTTP_METHOD'])) { 
      $this->method = $_SERVER['HTTP_METHOD']; 
      unset($_SERVER['HTTP_METHOD']); 
     } else { 
      $this->method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : false; 
     } 
     $this->protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : false; 
     $this->request_method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : false; 

     $this->headers = array(); 
     foreach($_SERVER as $i=>$val) { 
      if (strpos($i, 'HTTP_') === 0 || in_array($i, $this->add_headers)) { 
       $name = str_replace(array('HTTP_', '_'), array('', '-'), $i); 
       $this->headers[$name] = $val; 
      } 
     } 
    } 

    /** 
    * Retrieve HTTP Method 
    */ 
    function method() { 
     return $this->method; 
    } 

    /** 
    * Retrieve HTTP Body 
    */ 
    function body() { 
     return $this->body; 
    } 

    /** 
    * Retrieve an HTTP Header 
    * @param string Case-Insensitive HTTP Header Name (eg: "User-Agent") 
    */ 
    function header($name) { 
     $name = strtoupper($name); 
     return isset($this->headers[$name]) ? $this->headers[$name] : false; 
    } 

    /** 
    * Retrieve all HTTP Headers 
    * @return array HTTP Headers 
    */ 
    function headers() { 
     return $this->headers; 
    } 

    /** 
    * Return Raw HTTP Request (note: This is incomplete) 
    * @param bool ReBuild the Raw HTTP Request 
    */ 
    function raw($refresh = false) { 
     if (isset($this->raw) && !$refresh) { 
      return $this->raw; // return cached 
     } 
     $headers = $this->headers(); 
     $this->raw = "{$this->method} {$_SERVER['REQUEST_URI']} {$this->protocol}\r\n"; 

     foreach($headers as $i=>$header) { 
       $this->raw .= "$i: $header\r\n"; 
     } 
     $this->raw .= "\r\n{$this->body}"; 
     return $this->raw; 
    } 

} 

/** 
* Example Usage 
* Echos the HTTP Request back to the client/browser 
*/ 
$http_request = new http_request(); 

$resp = $http_request->raw(); 

echo nl2br($resp); 
/* Result (less <br> tags) 
    GET/HTTP/1.1 
    HOST: localhost:8080 
    USER-AGENT: Mozilla/5.0 ... 
    ACCEPT: text/html,application/xhtml+xml,application/xml;... 
    ACCEPT-LANGUAGE: en-US,en;q=0.5 
    ACCEPT-ENCODING: gzip, deflate 
    DNT: 1 
    COOKIE: PHPSESSID=... 
    CONNECTION: keep-alive 
*/ 
?> 

P. S: Dont zu htmlentities vergessen(), um sie Werte auf Ausgang :)

+0

np, ich abgekocht auch das Handbuch unnachgiebig muss es auch mit dem rohen Wunsch etwas, aber nicht abgesehen von einer PECL [HttpResponce ] (http://www.php.net/manual/en/class.httpresponse.php) oder [HttpMessage] (http://www.php.net/manual/en/class.httpmessage.php) Klassen aber dann Ich denke immer noch nicht, dass es Ihren Anforderungen entspricht, denke ich, vielleicht weil alle Werte analysiert und für $ _SERVER zur Verfügung gestellt werden, auf die Sie normalerweise zugreifen. –

+3

Es funktioniert eigentlich nicht perfekt. Dies ist eine verlustreiche Konvertierung, einige Details wie Leerzeichen und Gehäuse werden nicht beibehalten. – Pacerier

+3

Mehrere Header mit demselben Namen sind ein weiterer Bereich, in dem Informationen aus der ursprünglichen Anforderung verloren gehen. –

3

Die rohe Anfrage ist in PHP nicht verfügbar, da die Anforderung bereits durch die Zeit, PHP beginnt verbraucht wurde. Wenn PHP beispielsweise als Apache-Modul läuft (mod_php), wird die Anfrage von Apache empfangen und geparst, und PHP wird nur aufgerufen, nachdem Apache diese Anfrage analysiert hat und festgestellt hat, dass sie auf eine Datei verweist, die es sein sollte verarbeitet von PHP. Wenn PHP als CGI- oder FastCGI-Handler ausgeführt wird, empfängt es überhaupt keine HTTP-Anfrage - es sieht nur die CGI-Form der Anfrage, die ganz anders ist.

+0

Es ist immer noch möglich, dass PHP Apache nach der rohen Anfrage fragt. – Pacerier

+0

@Pacerier Nein, sorry; es ist nicht möglich. Apache speichert die rohe HTTP-Anfrage nirgendwo, da sie für nichts anderes verwendet wird. (In der Tat ist es für Apache möglich, eine Unteranfrage intern zu bearbeiten. In diesem Fall gibt es überhaupt keine Anfrage.) – duskwuff

0

Wenn Sie auf einem Apache-Maschine versuchen Sie dies:

function get_raw_http_request() { 

    $request = "{$_SERVER['REQUEST_METHOD']} {$_SERVER['REQUEST_URI']} {$_SERVER['SERVER_PROTOCOL']}\r\n"; 

    foreach (getallheaders() as $name => $value) { 
    $request .= "$name: $value\r\n"; 
    } 

    $request .= "\r\n" . file_get_contents('php://input'); 

    return $request; 
} 

http://php.net/manual/en/function.getallheaders.php