![Pensando](http://static.forosdelweb.com/fdwtheme/images/smilies/scratchchin.gif)
Tenía entendido que los headers no son enviados individualmente al navegador, sino que se envía una "compilación" al final de la ejecución del script.
Estuve haciendo unas pruebas. Por ejemplo:
Código PHP:
/* index.php */
session_start();
sleep(1); // Algo de procesamiento
header('Location: index2.php'); // Vamos a index2.php
sleep(4); // Más procesamiento
// Se supone que esta parte que sigue ya no llega a ejecutarse?
$_SESSION['foo'] = headers_sent();
Código PHP:
/* index2.php */
session_start();
echo '<pre>';
var_dump($_SESSION);
echo '</pre>';
Imprime
Código:
array(1) {
["foo"]=>
bool(false)
}
y ahí podemos apreciar 2 cosas: Primero, se supone que la variable de sesión ya no debería llegar a ser seteada, pues en 4 segundos el script ya debía haber cortado el procesamiento. Y segundo, headers_sent() me devuelve false, pues no se envió nada al navegador aún. Lo que sí se envía inmediatamente, sin esperar el fin de la ejecución, son las salidas de texto (HTML), o el usar flush(), etc.
Otro caso, más simple:
Código PHP:
sleep(1);
header('Location: index2.php');
sleep(5);
header('Location: index3.php');
Por medio de variables de sesión, o datos guardados en base de datos, se demuestra que nunca se pasó por index2.php, sino que el header enviado fue index3.php. Con HTTP Live headers para firefox se obtiene:
Código:
http://lab.okram/head/
GET /head/ HTTP/1.1
Host: lab.okram
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; es-AR; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: es-ar,es;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
HTTP/1.x 302 Found
Date: Tue, 16 Dec 2008 21:20:59 GMT
Server: Apache/2.2.8 (Win32) mod_ssl/2.2.8 OpenSSL/0.9.8g PHP/5.2.6
X-Powered-By: PHP/5.2.6
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Location: index3.php
Content-Length: 0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html
El header de redirección enviado sólo es el segundo, y eso que entre el primero y el segundo hubo 5 segundos de diferencia. Ocurre lo contrario si entre el primer y el segundo se hace un flush del contenido:
Código PHP:
sleep(1);
header('Location: index2.php');
flush();
sleep(5);
header('Location: index3.php');
No sé si tenga sentido o importancia discutir sobre esto. Pero estoy casi seguro de que verdaderamente el script se ejecutará siempre hasta que termine o se encuentre con un exit o die.