from - php force redirect
¿Se ejecutará el script PHP después de la redirección del encabezado? (9)
Sí, esta pregunta se ha formulado anteriormente, sin embargo, las respuestas han sido inconsistentes. Tomar ¿ Por qué tengo que llamar ''salir'' después de la redirección a través del encabezado (''Ubicación ..'') en PHP? por ejemplo. Cada respuesta (incluida la respuesta aceptada) indica que sí, excepto la última respuesta que recibió cero votos que dice "quizás". Estoy empezando a pensar que la respuesta correcta es "tal vez". Para que sea una simple pregunta de "sí" o "no", ¿se ejecutará DoThis () en el siguiente script? Gracias
header(''Location: http://somewhereElse.com'');
//die();
sleep(1000);
doThis();
EDITAR Gracias, todos. Con mi configuración de PHP / Linux / Apache, se ejecuta el segundo syslog (), por lo que la respuesta es "sí, se ejecutarán todas las secuencias de comandos del encabezado". Asumiré (y espero que sea correcto) que es lo mismo con todas las configuraciones de PHP / Linux / Apache.
<?php
header(''Location: http://google.com'');
syslog(LOG_INFO,''first'');
sleep(5);
syslog(LOG_INFO,''Second'');
?>
Déjame explicarte más. Tengamos un ejemplo usando sesión.
$_SESSION["username"] = ''some username'';
header("Location: another-file.php");
$_SESSION["username"] = ''replace username'';
El resultado de $_SESSION["username"]
será replace username
Puede generar muchos más encabezados que solo encabezados de Location
con encabezado, la mayoría de los cuales no desea detener la ejecución del código. Si desea detener la ejecución del código, debe llamar a exit
explícitamente.
El comando del header
no interrumpe el flujo de su código. Incluso si se encuentra, el navegador aún descarga su página, incluso si no se muestra. Considere las 404 pages
, que (a pesar de ser errores) aún son procesadas por el navegador (aunque se procesan mientras que las redirecciones no lo son).
ESCENARIO DE USECASE: Redirige a los usuarios al portal cautivo y luego inicia un temporizador de cuenta regresiva para eliminarlos de la lista de bloqueo después de x minutos.
Ejecutando el código:
//http://www.php.net/manual/en/function.header.php
header(''Location: http://google.com'');
flush();
sleep(3);
$a=fopen(''test.txt'', ''w'');
fwrite($a,headers_sent());
fclose($a);
El servidor hizo una pausa y escribió el archivo antes de que el cliente me redirigiera. Esto se debe a que, incluso después de flush()
el búfer, la redirección no se procesa hasta que la secuencia de comandos cesa la ejecución (es decir, la secuencia de comandos finalizó). El archivo test.txt
tenía ''1'' en todos los casos , lo que significa que los encabezados se enviaron, pero el navegador no los procesó hasta que se terminó la conexión.
- en todos los casos , es decir, en una máquina de desarrollo Win32, una máquina de desarrollo de Linux y un entorno de producción de Linux.
Este primer ejemplo muestra que algunos códigos se ejecutan después de la redirección de la ubicación del encabezado, pero que no todos los códigos se ejecutan necesariamente. Una vez que el navegador comienza a responder al encabezado de redirección, terminará la conexión en la página actual, lo que hará que PHP termine la ejecución de su código. Esto muestra cómo NO hacer las cosas.
session_start();
$_SESSION["some_value"] = ''original value'';
header("Location: /index.php/test2");
$start_time = microtime(true);
for($i = 0; $i <= 100000; $i ++)
{
password_hash($i); // slow it down
$_SESSION["some_value"] = $i;
$_SESSION[''time''] = microtime(true) - $start_time;
}
$_SESSION[''some_value''] = ''finished!'';
// Result:
// some_value = 174
En este ejemplo, agregué ignore_user_abort () para mostrar cómo ejecutar todo el código:
ignore_user_abort(TRUE);
session_start();
$_SESSION["some_value"] = ''original value'';
header("Location: /index.php/test2");
$start_time = microtime(true);
for($i = 0; $i <= 100000; $i ++)
{
password_hash($i); // slow it down
$_SESSION["some_value"] = $i;
$_SESSION[''time''] = microtime(true) - $start_time;
}
$_SESSION[''some_value''] = ''finished!'';
// Result:
// some_value = finished!
Y así es como normalmente ejecutaría una redirección, eliminando la secuencia de comandos inmediatamente después de la redirección:
session_start();
$_SESSION["some_value"] = ''original value'';
header("Location: /index.php/test2");
die();
$start_time = microtime(true);
for($i = 0; $i <= 100000; $i ++)
{
password_hash($i); // slow it down
$_SESSION["some_value"] = $i;
$_SESSION[''time''] = microtime(true) - $start_time;
}
$_SESSION[''some_value''] = ''finished!'';
// Result:
// some_value = original value
En resumen, use die (), exit () o ignore_user_abort (TRUE);
La gente parece estar realmente confundida, y en cuanto a por qué se ejecuta el script. Cuando envía el encabezado de redirección, el navegador redirige inmediatamente al usuario a la nueva página, pero su servidor continuará procesando el código aunque no haya nadie para recibirlo al final, esto no significa que el script haya finalizado. A menos que configure Apache para detener el script cuando se dé cuenta de que no hay nadie en el otro extremo.
Cuando un script PHP se ejecuta normalmente, el estado NORMAL está activo. Si el cliente remoto se desconecta, se enciende el indicador de estado ABORTADO. La desconexión de un cliente remoto suele deberse a que el usuario presiona el botón STOP.
Puede decidir si desea o no que una desconexión del cliente haga que su script sea abortado. A veces es útil tener siempre los scripts ejecutados hasta el final, incluso si no hay un navegador remoto que reciba la salida. Sin embargo, el comportamiento predeterminado es que la secuencia de comandos se anule cuando el cliente remoto se desconecta. Este comportamiento se puede establecer a través de la directiva
ignore_user_abort
php.ini, así como a través de la directivaignore_user_abort
ignore_user_abort correspondiente de Apache o con la funciónignore_user_abort()
.
La forma correcta de redirigir a un usuario sin más acciones es:
header("Location: blah.php");
exit();
Sí, la secuencia de comandos continúa procesándose después de la llamada al header(''Location: http://google.com'')
si no la termina explícitamente. Acabo de intentar esto localmente. Agregué test.php a un sitio en apache con estos contenidos:
<?php
header(''Location: http://google.com'');
error_log("WE MADE IT HERE SOMEHOW");
?>
Y revisé mi / var / log / apache2 / error_log para esta entrada:
[Tue Feb 12 23:39:23 2013] [error] [client 127.0.0.1] WE MADE IT HERE SOMEHOW
Posiblemente sorprendente, pero sí, continúa ejecutándose si no detienes la ejecución.
Sí, se ejecutará por corto tiempo.
Una vez que el encabezado de redireccionamiento se envía al navegador, el navegador cerrará la conexión actual y abrirá una nueva para la URL de redireccionamiento. Hasta que se cierre esa conexión original y Apache cierre el script, su código continuará ejecutándose como antes.
En teoría, si hubiera una conexión suficientemente rápida entre el cliente y el servidor, y no hubiera un búfer en ninguna parte de la tubería, la emisión del encabezado causaría la terminación del script de inmediato. En realidad, puede estar en cualquier lugar entre "ahora" y "nunca" para que se inicie el cierre.
sí sí sí, el encabezado es como cualquier otra parte del script php, se enviará después de que se complete la ejecución del script, sin embargo, el truco es: si queremos redirigir a una nueva URL: ¿por qué continuar ejecutando los scripts después del encabezado ("ubicación : url "); ?>
<?php
header(''Location: test.php'');
header(''Location: test.php'');
header(''Location: test.php'');
header(''Location: test.php'');
header(''Location: test.php'');
header(''Location: test.php'');
header(''Location: test.php'');
$var = ''google.com'';
header("Location: http://$var");
?>
header("Location: http://example.com/newURL.php");
die;
Sí, la secuencia de comandos continúa después de la redirección del encabezado, así que asegúrese de llamar a die;
o exit;
Cada vez que redireccione para detener la ejecución. No es necesario poner el script a dormir :).