33

はい、この質問は以前に尋ねられましたが、答えは一貫していません。PHPでheader('Location ..')を介してリダイレクトした後、なぜ'exit'を呼び出さなければならないのですか?例えば。「たぶん」と言うゼロ票を受け取った最後の回答を除いて、すべての回答(受け入れられた回答を含む)は「はい」と述べています。正解は「たぶん」だと思い始めています。単純な「はい」または「いいえ」の質問にするために、次のスクリプトを指定してdoThis()を実行しますか?ありがとう

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

編集ありがとう、すべて。私のPHP/Linux / Apache構成では、2番目のsyslog()が実行されるため、答えは「はい、ヘッダーの下流のすべてのスクリプトが実行されます」です。私はそれがすべてのPHP/Linux / Apache構成で同じであると仮定します(そして私が正しいことを願っています)!

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

10 に答える 10

31

はい、header('Location: http://google.com')明示的に終了しない限り、スクリプトはへの呼び出し後も処理を続行します。私はこれをローカルで試しました。これらのコンテンツを含むapacheのサイトにtest.phpを追加しました。

<?php

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

?>

そして、私の/ var / log / apache2 / error_logでこのエントリを確認しました:

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

おそらく驚くべきことですが、実行を停止しない限り、実行を継続します。

于 2013-02-13T05:41:25.567 に答える
12

人々はこれを本当に混乱させているようで、なぜスクリプトが実行されるのかについてです。リダイレクトヘッダーを送信すると、ブラウザはすぐにユーザーを新しいページにリダイレクトしますが、最後にコードを受信する人がいない場合でも、サーバーはコードを処理し続けます。これは、スクリプトが終了したことを意味するものではありません。相手側に誰もいないことに気付いたときにスクリプトを停止するようにApacheを設定しない限り。

PHPスクリプトが正常に実行されている場合、NORMAL状態がアクティブになります。リモートクライアントが切断すると、ABORTED状態フラグがオンになります。リモートクライアントの切断は通常、ユーザーがSTOPボタンを押すことによって発生します。

クライアントを切断してスクリプトを中止するかどうかを決定できます。出力を受信するリモートブラウザがない場合でも、スクリプトを常に実行して完了すると便利な場合があります。ただし、デフォルトの動作では、リモートクライアントが切断されたときにスクリプトが中止されます。この動作は、 ignore_user_abortphp.iniディレクティブ、対応するphp_value ignore_user_abortApache httpd.confディレクティブ、または ignore_user_abort()関数を使用して設定できます。

それ以上のアクションなしでユーザーをリダイレクトする正しい方法は次のとおりです。

header("Location: blah.php");
exit();
于 2015-05-25T03:50:21.673 に答える
5

もっと説明させてください。セッションを使用した例を見てみましょう。

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

結果$_SESSION["username"]replace username

ヘッダー付きのヘッダーよりもはるかに多くのヘッダーを出力できますがLocation、そのほとんどはコードの実行を停止したくないものです。コードの実行を停止する場合は、exit明示的に呼び出す必要があります。

このheaderコマンドは、コードの流れを中断しません。それが発生した場合でも、ページが表示されていなくても、ページはブラウザによってダウンロードされます。(エラー404 pagesであるにもかかわらず)ブラウザによって処理されます(リダイレクトはレンダリングされませんが)。

于 2013-02-13T05:44:26.123 に答える
3

コードの実行:

//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()、バッファを使用した後でも、スクリプトの実行が停止する(つまり、スクリプトが終了する)までリダイレクトが処理されないためです。ファイルにはすべてtest.txt「1」が付いていました。これは、ヘッダーが送信され、接続が終了するまでブラウザによって処理されなかったことを意味します。

  • いずれの場合も、win32開発マシン、Linux開発マシン、およびLinux実稼働環境を意味します。
于 2013-02-13T05:51:34.337 に答える
2

この最初の例は、ヘッダーの場所のリダイレクト後に一部のコードが実行されることを示していますが、必ずしもすべてのコードが実行されるわけではありません。ブラウザがリダイレクトヘッダーへの応答を開始すると、現在のページで接続が終了します。これにより、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!

そして、これは、リダイレクトの直後にスクリプトを強制終了することにより、通常、リダイレクトを実行する方法です。

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)のいずれかを使用します。

于 2017-02-28T17:17:42.160 に答える
2

リダイレクトが完了した後も、スクリプトは実行されます。役に立つこともあるかもしれませんが、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非常に危険である可能性があることに注意してください。
...通常、パスワードなどのデータをプレーンテキストで保存したり、ログインしたCookieなどの情報を保存したりしないことを忘れないでください

于 2019-05-21T16:00:42.073 に答える
1

はい、短時間で実行されます。

リダイレクトヘッダーがブラウザに送信されると、ブラウザは現在の接続を閉じ、リダイレクトURL用に新しい接続を開きます。元の接続が閉じられ、Apacheがスクリプトをシャットダウンするまで、コードは以前と同じように実行され続けます。

理論的には、クライアント/サーバー間に十分に高速な接続があり、パイプラインのどこにもバッファリングがない場合、ヘッダーを発行すると、スクリプトがすぐに終了します。実際には、シャットダウンが開始されるのは「現在」と「決して」の間のどこでもかまいません。

続きを読む

于 2013-02-13T05:42:34.853 に答える
0

はいはいはい、ヘッダーはphpスクリプトの他の部分と同様に、スクリプトの実行が完了した後に送信されますが、トリックは次のとおりです。新しい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");

?> 
于 2013-02-13T05:49:58.857 に答える
0
header("Location: http://example.com/newURL.php");
die;

はい、スクリプトはヘッダーリダイレクト後も続行されるため、必ず呼び出すdie;exit;、リダイレクトするたびに実行を停止してください。スクリプトをスリープ状態にする必要はありません:)。

PHPでリダイレクトする方法は?

于 2017-02-10T17:14:12.643 に答える
-1

ユースシナリオ:ユーザーをキャプティブポータルにリダイレクトし、カウントダウンタイマーを開始して、x分後にブロックリストからユーザーを書き込みます。

于 2017-10-17T14:32:42.993 に答える