2015-08-10 21 views
10

Ho incontrato accidental usage dell'intestazione Status per FastCGI. Esistono vantaggi/svantaggi di utilizzarlo in script indipendenti dall'ambiente?Reindirizzamento 301/302 indipendente dall'ambiente con PHP

header('Location: ' . $url, true, 301); 

da solo non provoca problemi per me su Apache 2.2 (secondo phpinfo(), il server utilizza FastCGI).

Lo script è destinato ad Apache e nginx (mod_php e FastCGI). Come sarebbe la soluzione a prova di errore?

+1

Buona domanda. Mi inclino all'intestazione '(HTTP/1.1 301 '. $ Url, true, 301);' Forse ridondante? Vorrei vedere il codice sottostante ora. In che modo tutto ciò tiene conto dell'uso di ['http_response_code'] (http://php.net/http_response_code), mi chiedo. – ficuscr

risposta

4

Il codice di stato HTTP viene emesso come parte della prima riga della risposta HTTP. Secondo Fast CGI FAQ l'intestazione Stato è un'intestazione speciale riconosciuta dal server che controlla questa linea e non viene inviata al client. Tuttavia, se viene utilizzato con un adattatore server non FastCGI, il valore viene ignorato dal server e l'intestazione può essere inviata.

La soluzione che già possiedi è la più indipendente dall'ambiente possibile. L'unica aggiunta sarebbe una dichiarazione exit immediatamente dopo il reindirizzamento per assicurarsi che lo script termini.

Guardiamo cosa succede sotto il cofano più da vicino.

Il seguente reindirizzamento PHP codice

header('Location: ' . $url, true, 301); 
exit; 

chiamerà il codice C in ext/standard/head.c

PHP_FUNCTION(header) 
{ 
    [ code that just parses the arguments omitted ] 

    sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr); 
} 

che a sua volta chiama la funzione sapi_header_op in main/SAPI.c

[ ... ] 

switch (op) { 

    [ ... ] 

    case SAPI_HEADER_ADD: 
    case SAPI_HEADER_REPLACE: 
    case SAPI_HEADER_DELETE: { 
      sapi_header_line *p = arg; 

      if (!p->line || !p->line_len) { 
       return FAILURE; 
      } 
      header_line = p->line; 
      header_line_len = p->line_len; 
      http_response_code = p->response_code; 
      break; 
     } 

[ code that splits header line by colon, trims whitespace etc ] 

[ special headers handling code, including setting 302 if Location ] 

if (http_response_code) { 
    sapi_update_response_code(http_response_code); 
} 

sapi_header_add_op(op, &sapi_header); 
return SUCCESS; 

Se FastCGI indietro -end è in uso, le intestazioni aggiunte saranno eventua lly essere inviato dal sapi_cgi_send_headers funzione sapi/cgi/cgi_main.c

[ ... ] 
if (CGIG(nph) || SG(sapi_headers).http_response_code != 200) 
{ 
    [ emit status line if cgi.rfc2616-headers is set ] 

    [ Handle a case where there is a user supplied status line ] 

    [ Handle a case where there is already a user supplied status header ] 

    [ if none of the above ] 

     if (err->str) { 
      len = slprintf(buf, sizeof(buf), "Status: %d %s\r\n", SG(sapi_headers).http_response_code, err->str); 
     } else { 
      len = slprintf(buf, sizeof(buf), "Status: %d\r\n", SG(sapi_headers).http_response_code); 
     } 
    [ ... ] 
} 
[ ... ] 

noti che php_apache_sapi_send_headers funzione sapi/apache2handler/sapi_apache2.c non ha una gestione speciale dell'intestazione Status perché non è utilizzato per la comunicazione modulo.

Quindi eseguendo il codice PHP sopra

  1. Codice di risposta nella riga di stato HTTP è costretto a 301
  2. posizione sono sommati intestazione o quello esistente è sostituita
  3. Lo script esce in modo che nessun il codice successivo può cambiare lo stato o le intestazioni

Tutte le manipolazioni vengono eseguite nel livello SAPI che è un livello di astrazione sopra gli adattatori del server HTTP (FastCGI, Apa che modulo ecc.). Questo è cross-environment e affidabile come diventa.

Storicamente ci sono stati errori in FastCGI che hanno impedito il corretto funzionamento delle 301 risposte, tuttavia queste erano nell'implementazione del server Web e non c'era nulla che potesse essere fatto dal codice PHP per risolvere il problema.

Consulta anche:

+0

Questa è la spiegazione che mi mancava. Grazie per la risposta esauriente supportata dai riferimenti di origine. – estus

Problemi correlati