Будет ли выполняться PHP скрипт после перенаправления заголовка?

Да, этот вопрос задавали раньше, однако ответы были непоследовательными. Возьмем Почему мне нужно вызывать "exit" после перенаправления через заголовок ( "Местоположение.." ) в PHP?. В каждом ответе (включая принятый ответ) говорится: да, кроме последнего ответа, который получил нулевые голоса, который говорит "может быть". Я начинаю думать, что правильный ответ "возможно". Чтобы сделать это простым вопросом "да" или "нет", будет выполнено doThis() с учетом следующего script? Благодаря

header('Location: http://somewhereElse.com');
//die();
sleep(1000);
doThis();

ИЗМЕНИТЬ Спасибо всем. С моей конфигурацией PHP/Linux/Apache выполняется второй syslog(), поэтому ответ "да", будет выполняться нисходящий поток заголовка script ". Я предполагаю (и надеюсь, что я прав), это то же самое со всеми конфигурациями PHP/Linux/Apache!

<?php
  header('Location: http://google.com');
  syslog(LOG_INFO,'first');  
  sleep(5);
  syslog(LOG_INFO,'Second');  
?>

Ответ 1

Да, script продолжает обрабатывать после вызова header('Location: http://google.com'), если вы его явно не завершаете! Я просто попробовал это на месте. Я добавил test.php на сайт в apache с этим содержимым:

<?php

header('Location: http://google.com');
error_log("WE MADE IT HERE SOMEHOW");

?>

И проверил мой /var/log/apache 2/error_log для этой записи:

[Tue Feb 12 23:39:23 2013] [error] [client 127.0.0.1] WE MADE IT HERE SOMEHOW

Возможно, это удивительно, но да, он продолжает выполняться, если вы не прекращаете выполнение.

Ответ 2

Кажется, что люди действительно запутались, и о том, почему выполняется script. Когда вы отправляете заголовок переадресации, браузер сразу перенаправляет пользователя на новую страницу, но ваш сервер будет продолжать обрабатывать код, даже если его нет в конце, это не означает, что script завершается. Если вы не настроите Apache, чтобы остановить script, когда он реализует, на другом конце нет никого.

Когда PHP script работает нормально, состояние NORMAL является активным. Если удаленный клиент отключает флаг состояния ABORTED, он включается. Отключение удаленного клиента обычно вызвано тем, что пользователь нажал кнопку STOP.

Вы можете решить, хотите ли вы, чтобы клиент отключился ваш script будет прерван. Иногда бывает удобно всегда иметь сценарии выполняются до завершения, даже если нет удаленного доступа к браузеру выход. Однако поведение по умолчанию для вашего script должно быть прерывается, когда удаленный клиент отключается. Такое поведение можно установить через директиву ignore_user_abort php.ini, а также через Соответствующая php_value ignore_user_abort Директива Apache httpd.conf или с помощью функции ignore_user_abort().

Правильный способ перенаправления пользователя без дальнейших действий:

header("Location: blah.php");
exit();

Ответ 3

Позвольте мне объяснить больше. дайте пример, используя сеанс.

$_SESSION["username"] = 'some username';
header("Location: another-file.php");
$_SESSION["username"] = 'replace username';

Результат $_SESSION["username"] будет replace username

Вы можете выводить намного больше заголовков, чем заголовки Location с заголовком, большинство из которых вы не хотите останавливать выполнение кода. Если вы хотите прекратить выполнение кода, вам нужно явно вызвать exit.

Команда header не прерывает поток вашего кода. Даже если это встречается, ваша страница все еще загружается браузером, даже если она не отображается. Рассмотрим 404 pages, которые (несмотря на ошибки) все еще обрабатываются браузером (хотя они отображаются, а перенаправления - нет).

Ответ 4

Запуск кода:

//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);

Сервер остановился и написал файл до того, как клиент перенаправил меня. Это связано с тем, что даже после flush() ввода буфера перенаправление не обрабатывается до тех пор, пока script не прекратит выполнение (т.е. script завершено). Файл test.txt имел "1" в каждом случае, что означает, что заголовки были отправлены, просто не обработаны браузером до тех пор, пока соединение не будет прекращено.

  • в каждом случае, что означает на машине разработки win32, машине разработки Linux и среде производства Linux.

Ответ 5

Этот первый пример показывает, что некоторый код выполняется после перенаправления местоположения заголовка, но не все коды обязательно выполняются. После того, как браузер начнет отвечать на заголовок перенаправления, он прекратит соединение на текущей странице, что заставит PHP прекратить выполнение своего кода. Это показывает, как НЕ делать что-то.

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

В этом примере я добавил ignore_user_abort(), чтобы показать, как выполнить весь код:

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!

И так вы обычно выполняете перенаправление, убивая script сразу после перенаправления:

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

Короче говоря, либо используйте die(), exit(), либо ignore_user_abort (TRUE);

Ответ 6

Да, он будет выполнен в течение короткого промежутка времени.

Как только заголовок перенаправления отправляется в браузер, браузер будет закрыть текущее соединение и открыть новый для URL-адреса переадресации. Пока это оригинальное соединение не будет закрыто, и Apache выключит script, ваш код будет продолжать выполняться по-прежнему.

Теоретически, если бы существовала достаточно быстрая связь между клиент/сервер, и не было никакой буферизации в любом месте трубопровода, выдача заголовка приведет к прекращению действия scriptнемедленно. В действительности это может быть где угодно между "сейчас" и "никогда", для запуска выключения.

Подробнее

Ответ 7

да да да, заголовок подобен любой другой части php script, он будет отправлен после завершения выполнения script, трюк: если мы хотим перенаправить на новый URL-адрес: тогда зачем продолжать выполнение сценариев после заголовка ( "location: 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");

?> 

Ответ 8

header("Location: http://example.com/newURL.php");
die;

Да script продолжается после перенаправления заголовка, поэтому обязательно вызывайте die; или exit; при каждом перенаправлении, чтобы остановить выполнение. Не нужно ставить script в режим сна:).

Как сделать перенаправление в PHP?

Ответ 9

Сценарий все еще будет работать после того, как перенаправление выполнено. Хотя иногда это может быть полезно, люди, которые используют функцию header, должны знать, что это может быть опасно. Посмотрите на этот кусок очень небезопасного кода:

<?php
if($_GET['some_secret'] != '123') {
    setcookie("status", "not logged in");
    header("Location: /");
}
setcookie("status", "logged in");

echo("Some secret info!")
?>

Независимо от того, что вы вводите some_secret, у вас всегда будет файл cookie со зарегистрированным значением. Единственная разница здесь в том, что пользователь будет перенаправлен, если задано неправильное значение параметра.

Решение. Используйте метод die() или exit() чтобы завершить выполнение сценария сразу после перенаправления.

Это небольшое исправление сделает наш скрипт работающим так, как мы хотели.

<?php
if($_GET['some_secret'] != '123') {
    setcookie("status", "not logged in");
    header("Location: /");
    die();
}
setcookie("status", "logged in");

echo("Some secret info!")
?>

(Я не буду показывать другое простое решение с оператором else, поскольку на самом деле это не так, как должно быть.)


Вы можете подумать, что пользователь по крайней мере не увидит секретную информацию, которую вы печатаете на экране. НЕПРАВИЛЬНО! Браузер просто делает перенаправление, но это до нас, если мы последуем за ним.

В этом примере я использовал уязвимый код без die:

$ telnet 192.168.1.39 80
Trying 192.168.1.39...
Connected to 192.168.1.39.
Escape character is '^]'.
GET /test.php?some_secret=wrong
Some secret info!
Connection closed by foreign host.

Как видите, секретная информация просочилась.

Итак, имейте в виду, что header может быть очень опасным!
... и помните, что обычно не храните такие данные, как пароли, в виде открытого текста или информацию, например, вошедшую в куки

Ответ 10

СЦЕНАРИЙ USECASE: перенаправляйте пользователей к порталу для записи, затем запускайте таймер обратного отсчета, чтобы записать их из списка блоков через x минут.