2014-05-03 4 views
6

Je cherche un moyen d'obtenir, en utilisant PHP natif, la requête HTTP brute reçue par mon script, y compris les en-têtes et le corps. En lisant la documentation PHP, je ne trouve pas de moyen standard pour obtenir la requête brute, quelle que soit la méthode HTTP utilisée.Obtenir la requête brute en utilisant PHP

Par exemple, lorsque la test.php page est demandée, je veux obtenir la demande complète comme:

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

Le même en cas de POST, HEAD, etc ...

Semble très étrange qu'il n'existe pas de méthode pour accéder au buffer de requête raw!

Répondre

10

En regardant par-dessus le manuel, il ne semble pas y avoir un accès brut non réparé à la requête pour correspondre à ce que vous voulez, donc je suppose que vous devrez reconstruire ce que vous voulez à partir des variables $_SERVER. Une recherche rapide, j'ai trouvé cette classe, fait quelques petits changements pour obtenir le GET/HTTP/1.1, peut-être vous le trouverez pour répondre à vos besoins.

<?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: Ne pas oublier de htmlentities() les valeurs sur la sortie :)

+0

np, moi aussi parcouru le inflexibles manuel, il doit y avoir quelque chose à la demande brute aussi, mais pas en dehors d'un PECL [HttpResponce ] (http://www.php.net/manual/en/class.httpresponse.php) ou [HttpMessage] (http://www.php.net/manual/en/class.httpmessage.php) classes mais Je ne pense toujours pas qu'il répond à vos exigences, je pense que peut-être parce que toutes les valeurs sont analysées et mises à la disposition de '$ _SERVER', qui est généralement la façon dont vous y accédez. –

+3

Cela ne fonctionne pas parfaitement. C'est une conversion avec perte, certains des détails comme les espaces et le boîtier ne sont pas conservés. – Pacerier

+3

Plusieurs en-têtes avec le même nom sont une autre zone où cela perd l'information de la demande d'origine. –

3

La demande brute n'est pas disponible à PHP, parce que la demande a déjà été consommée par le temps PHP commence. Lorsque PHP s'exécute en tant que module Apache (mod_php), par exemple, la requête est reçue et analysée par Apache, et PHP n'est invoqué qu'après qu'Apache a analysé cette requête et déterminé qu'il fait référence à un fichier qui doit être traité par PHP. Si PHP s'exécute en tant que gestionnaire CGI ou FastCGI, il ne reçoit jamais de requête HTTP - il ne voit que la forme CGI de la requête, ce qui est assez différent.

+0

Il est toujours possible que PHP demande à Apache la requête brute. – Pacerier

+0

@Pacerier Non, désolé; ce n'est pas possible. Apache ne stocke pas la requête HTTP brute n'importe où, car il ne sert à rien d'autre. (En fait, Apache peut gérer une sous-requête en interne, auquel cas il n'y a aucune requête brute.) – duskwuff

0

Si vous êtes sur une machine Apache, essayez ceci:

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

Questions connexes