【超至急】PHPにおいて、リロード対策のための方法がうまくいかず困っております。


a.php実行後、b.phpに遷移してからリロードすると以下結果となります。
★の動作を期待していますが、原因不明でどこに問題があるか困っております。
ソースはそのまま動作します。推測ではなく、実際に動作確認の上でご教授をお願いいたします。

■実行結果(a.phpからの流入時)
 window.name : http://www.xxxx.com/a.php
 window.href : http://www.xxxx.com/b.php
result : not reload
■実行結果(b.php遷移後にリロード)
 window.name : http://www.xxxx.com/b.php
 window.href : http://www.xxxx.com/b.php
result : not reload ← ★ここが"result : reload"となることを期待しています
■ソース(a.php)
<?php
echo '<script type="text/javascript">window.name="http://www.xxxx.com/a.php";
</script>';
echo '<a href="http://www.xxxx.com/b.php">link</a>';
?>
■ソース(b.php)
<?php
$w_name = '<script language="JavaScript">document.write(window.name);</script>';
$w_href = '<script language="JavaScript">document.write(window.location.href);</script>';
echo "window.name :" . $w_name . "<br>";
echo "window.href :" . $w_href . "<br>";

if ($w_name !== $w_href) {
echo "result : not reload";
echo '<script language="JavaScript">window.name = window.location.href;</script>';} else {
echo "result : reload";
}
?>

回答の条件
  • 1人1回まで
  • 登録:
  • 終了:2017/04/19 00:55:16
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:a-kuma3 No.1

回答回数4973ベストアンサー獲得回数2154

ポイント500pt

コメントで書かれているセッションに目印をつけておく方法以外では、こんな方法もあるようです。
https://www.yourhowto.net/detect-page-refresh-php/

<?php
$pageWasRefreshed = isset($_SERVER['HTTP_CACHE_CONTROL']) && $_SERVER['HTTP_CACHE_CONTROL'] === 'max-age=0';
 
if($pageWasRefreshed ) {
    //do something because page was refreshed;
} else {
    //do nothing;
}

stackoverflow なんかでも、ちょいちょい回答に使われているコードのようです。

質問のコードに合わせて書くと、b.php は、こんな感じ。

<?php
$pageWasRefreshed = isset($_SERVER['HTTP_CACHE_CONTROL']) && $_SERVER['HTTP_CACHE_CONTROL'] === 'max-age=0';
 
if($pageWasRefreshed ) {
    echo "result : reload";
} else {
    echo "result : not reload";
}
?>

セッションに目印を持っておくやり方は、「いつ、目印を外すか」というのが、結構 難しい。
先に引用したふたつの方法のうちのふたつ目がセッションに目印を持っておくやり方ですけれど、このままでは、別のところに行って戻ってきた場合にもリロードと判定されてしまいます。

a.php
 ↓
b.php : セッションに目印をつける
 ↓
b.php : 目印があるので、リロードと判定
 ↓
c.php : 別のところに行く
 ↓
b.php : セッションの目印が残ってるので、リロードと判定されてしまう

b.php で、期待通りの操作をされたときの飛び先のページ(例えば、「完了しました」みたいなページ)で、セッションの目印を消してあげる必要があります。

id:a-kuma3

質問のソースでwindow.nameとwindow.location.hrefの値がb.php遷移後に同じ値で取れているにも関わらず、if ($w_name !== $w_href)にヒットしてしまうことが混乱の原因で、未だにわかりません。モヤモヤが残りますが、

php のスクリプトはどこで解釈されて、javascript はどこで解釈されているでしょうか。

a.php のリンクをクリックされる
 ↓
Webサーバにリクエストが送信され、b.php が Web サーバで実行される(javascript を PHP は解釈できない)
 ↓
b.php は、以下のレスポンスをブラウザに返す
>>
window.name:<script language="JavaScript">document.write(window.name);</script><br>
window.href:<script language="JavaScript">document.write(window.location.href);</script><br>
result : not reload
<script language="JavaScript">window.name = window.location.href;</script>
<<
 ↓
b.php のレスポンスを受けて、javascript が実行される。
script タグの内側が解釈されて、以下のように表示される。
>>
window.name:
window.href:http://foo.com/b.php
result : not reload
<<

b.php を Webサーバで処理しているときには、PHP は javascript を解釈(実行)できないので、
$w_href は "http://foo.com/b.php" ではなく、"<script language="JavaScript">document.write(window.location.href);</script>" という文字列なんです($w_name も同様)。

2017/04/19 00:36:53
id:cochoo

a-kuma3様
いろいろと丁寧なご回答をいただきありがとうございます。仰る通りでPHPを誤解しておりました。
業務でSESSION変数やSERVER変数が使えないため、どうすればよいか悩んでおりました。
ご指摘を受けてすべてjavascriptで実装し、XMLHttpRequestで状態をPOSTして自身のPHP側に渡すことで解決できました。

b.php
if (window.name != window.location.href) { //alert("not reload"); var xhr = new XMLHttpRequest(); xhr.open('POST', 'b.php'); xhr.send(); window.name = window.location.href; // ここで初期化} else { //alert("reload");}</script>
明確なご指摘をいただいたため、ベストアンサーとさせていただきます。ありがとうございました。

2017/04/19 00:55:01
  • id:TransFreeBSD
    ソースを間違えていませんか?
    "result : reload"となるには$w_name == $w_hrefとなる必要がありますが、両者は異なる固定文字列ですので等しくなる要素がありませんから、"result : reload"となる要素が見当たりません。

    目的が分かりませんが、セッションを利用するのが一般的だと思います。
  • id:TransFreeBSD
    window.nameで判定したいということならif文もjavascriptである必要があります。phpは使えません。
  • id:uunfo
    何をやりたいのかが全く分からない。

    何のためにPHPを使っているのか、まったくわからない。
    以下のHTMLソースと全く同じってことわかってますか?

    ■ソース(a.php)
    <script type="text/javascript">window.name="http://www.xxxx.com/a.php
    </script>
    <a href="http://www.xxxx.com/b.php">link</a>

    ■ソース(b.php)
    window.name :<script language="JavaScript">document.write(window.name);</script><br>
    window.href :<script language="JavaScript">document.write(window.location.href);</script><br>
    result : not reload
    <script language="JavaScript">window.name = window.location.href;</script>
  • id:cochoo
    TransFreeBSD様
    セッションでは、たとえば以下のようにすればよいのですが、業務でSESSION変数が使えません。
    a.php
    $_SESSION["key"] = md5(uniqid().mt_rand());
    <a href="b.php">link</a>
    b.php
    if (isset($_SESSION['key'])) {
    // not reload
    unset($_SESSION['key']);
    }
    PHPは読み込まれた時点で完成されていますので、windows.nameを動的に判定する場合は、
    javascriptであるご指摘もわかります。
    結局、javascriptでHttpRequestでPOSTすることで自己解決できましたが、
    質問のソースでwindow.nameとwindow.location.hrefの値がb.php遷移後に同じ値で取れているにも関わらず、if ($w_name !== $w_href)にヒットしてしまうことが混乱の原因で、未だにわかりません。モヤモヤが残りますが、解決方法が見つかりましたので、Closeといたします。ありがとうございました。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません