Secuencia de comandos de PHP header () “crashing” con error HTTP 500

Yo uso PHP 5.2.9.

Para ver / registrar errores, al comienzo de mi script tengo:

error_reporting(E_ALL | E_STRICT); ini_set('display_errors', 'On'); ini_set('log_errors', 'On'); ini_set('error_log', $_SERVER['DOCUMENT_ROOT'] . '/php.log'); 

Pero cuando uso la primera de las siguientes dos líneas, mi secuencia de comandos genera un error HTTP 500, y no se muestra nada (excepto el error 500) y no se registra nada en mi php.log. Si utilizo la segunda línea en lugar de la primera, todo está bien y el 304 se emite normalmente.

 header('Not Modified', true, 304); //Crash php with 500 error header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified', true, 304); //Works OK //In both case exit(); is called just after header(). 

¿No son estas dos líneas equivalentes (ver enlace a continuación)? ¿Por qué la primera versión “bloquea” mi script?

Esto está relacionado con: uso de encabezado en PHP

Editar 1: este es el único registro que puedo encontrar:

 ' 69.70.84.xx - - [20/Jan/2010:15:54:06 -0600] "GET /framework2/ HTTP/1.1" 200 2968 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)" 69.70.84.xx - - [20/Jan/2010:15:54:08 -0600] "GET /foo/bar.js HTTP/1.1" 404 8642 "http://www.mydomain.com/framework2/" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)" 69.70.84.xx - - [20/Jan/2010:15:54:10 -0600] "GET /framework2/ HTTP/1.1" 500 8511 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)" 69.70.84.xx - - [20/Jan/2010:15:54:11 -0600] "GET /framework/mydomain_ajax-dom.js HTTP/1.1" 304 - "http://www.mydomain.com/framework2/" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)" 69.70.84.xx - - [20/Jan/2010:15:54:11 -0600] "GET /framework/templates/common/Reset.css HTTP/1.1" 304 - "http://www.mydomain.com/framework2/" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)" 69.70.84.xx - - [20/Jan/2010:15:54:11 -0600] "GET /framework/templates/common/Error.css HTTP/1.1" 304 - "http://www.mydomain.com/framework2/" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)" 69.70.84.xx - - [20/Jan/2010:15:54:11 -0600] "GET /framework/templates/common/Base.css HTTP/1.1" 304 - "http://www.mydomain.com/framework2/" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)" 69.70.84.xx - - [20/Jan/2010:15:54:11 -0600] "GET /images/Error-48.png HTTP/1.1" 304 - "http://www.mydomain.com/framework2/" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)" ' 
  1. La línea 1 es el documento correctamente servido.
  2. La línea 2 es el 404 de un .js ficticio en mi documento.
  3. La línea 3 es donde se produce el error real (pulso actualizar en mi navegador y mi problema PHP el encabezado 304 que bloquea mi secuencia de comandos).
  4. Las líneas 4, 5, 6, 7 y 8 son causadas por mi mensaje de error personalizado (a través de .htaccess) que muestra el mensaje de error 500.

Editar 2: me puse en contacto con el soporte del host web para preguntar si tenía acceso a más registros; me dijeron que no, pero de su lado tienen acceso a los registros que no puedo ver. Mi error estaba ahí:

 'backend: malformed header from script. Bad header=Not Modified: index.php' 

Así que de vuelta a mi pregunta … ¿Por qué en algunos hosts la primera versión no funciona y en otros parece estar bien (peor aún alguien en el enlace de arriba dice que el segundo falla mientras que el primero está bien) ??

No, esas líneas no son equivalentes. El primero escribirá una línea de encabezado no válida. La documentación de la función de header dice:

header() se usa para enviar un encabezado HTTP sin procesar.

Y en la descripción del parámetro de cadena :

Hay dos llamadas a encabezados de casos especiales. El primero es un encabezado que comienza con la cadena “HTTP /” (caso no es significativo), que se usará para descubrir el código de estado HTTP que se enviará.

En su caso, el valor Not Modified no comienza con HTTP/ y, por lo tanto, no se trata para establecer el código de estado HTTP sino solo un campo de encabezado regular. Pero no es válido ya que no tiene la forma:

 message-header = field-name ":" [ field-value ] 

Y eso es lo que indica la entrada del registro de errores. Not Modified no es un encabezado HTTP sin formato válido.

El tercer parámetro http_response_code es solo establecer el código de estado mientras se configura una redirección para evitar dos llamadas al header como:

 header('HTTP/1.1 301 Moved Permanently'); header('Location: http://example.com'); 

En lugar de eso, simplemente puedes escribir:

 header('Location: http://example.com', true, 301); 

En este caso, querrá consultar el registro de errores de su servidor web, no el registro de errores de PHP, para obtener más información sobre el locking.