こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

php フォーム開発 IE9のみセッション消滅

フォーム機能での、「入力画面」>「確認画面」>修正するボタン>「入力画面」
という流れの中の、ブラウザIE9でのセッションの消滅について質問させてください。
はまってしまってから3日になります。とうとう力尽きました。
IE9以外の下位バージョンやFireFoxでは問題なく動きます。

まず、環境から。
xmpp 1.7.3
PHP 5.3.1
MySQL 5.1.41
Smarty 3.0.7
※同一ドメインで、フォームを複数運営させるため、
各フォームのそれぞれの項目(ラジオ,チェックボックス,テキストエリアなど)を管理画面から一意の値と共にDBに格納しています。
各フォームを表示する際は、その一意の値を呼び出して出力しています。


次に、処理の流れです。

(1)「入力画面」では、各入力項目をDBから取得し、少し整形してフォーム画面を出力しています。
Smartyを使っていますので、テンプレートへ アサインする形です。
※この際、$_SESSION["f"]["no"]に、フォームを大別する一意の値を入れています。

閲覧者が入力した内容は、自身「入力画面.php」にポストして、
空の判別後、$_SESSION["f"]["別の一意の数値"]に保存します。
その直後、エラーチェック関数にそのセッションを通して、通過すれば「確認画面」へリダイレクトします。

/*下記のように*/
$url = "http://".$_SERVER["HTTP_HOST"].dirname($_SERVER["SCRIPT_NAME"])."/確認画面.php";
header("Location: ".$url);
exit;


(2)「確認画面」では、
「入力画面」を経由したかどうかをphpの先頭でチェックします。
上述の$_SESSION["f"]["別の一意の数値"]を使って、同じエラーチェック関数で審査を行い、
通過すれば「確認画面」を表示するようにしています。
※実際は、このチェックの前に$_SESSION["f"]["no"]を使ってDBから値を取得したりしています。

/*下記のように*/

$p[2]=フォーム取得関数($_SESSION["f"]["no"]);//DBからフォームに関する個別の値を取得。

if(count($p[2])!=0){
if(エラーチェック関数($_SESSION["f"])){
//エラー 入力画面経由ではないので 「入力画面」へ戻す
$url = "http://".$_SERVER["HTTP_HOST"].dirname($_SERVER["SCRIPT_NAME"])."/入力画面?no=".$_SESSION["f"]["no"];
header("Location: " . $url);
exit;
}

}else{
//エラー フォーム関連パーツを取得できないので 「入力画面」へ戻す
$url = "http://".$_SERVER["HTTP_HOST"].dirname($_SERVER["SCRIPT_NAME"])."/入力画面?no=".$_SESSION["f"]["no"];
header("Location: " . $url);
exit;
}


(3)問題なければ、
「確認画面」が表示されます。


(4)内容を修正するのであれば、
「修正するボタン」を押して >「入力画面」へと遷移させます。
/*下記のように*/

<テンプレート内>
<form action="確認画面.php" method="post">
<input type="submit" name="modify" value="   修正する   ">
</form>

<確認画面.php内>
if(isset($_POST["modify"]){
$url = "http://".$_SERVER["HTTP_HOST"].dirname($_SERVER["SCRIPT_NAME"])."/入力画面?no=".$_SESSION["f"]["no"];
header("Location: ".$url);
exit;
}

(5)確認画面からゲットでnoの値を受ける(入力画面にて)
<入力画面.php内>
if(isset($_GET["no"]) && is_numeric($_GET["no"])){

//$_GET["no"]つまり$_SESSION["f"]["no"]を使ってDBの値取得
}
そしてセッションを維持したままなので、前回の入力項目を修正することができる。


これらの一連の流れは、IE9以外だと正しく動きます。
IE8も含めIE7 IE6 でも正常に動きます。



しかし、(4)の段階で、$_SESSION["f"]["no"]の値が消滅している為か、「入力画面」へと戻ることができません。
細かく言えば、(2)や(3)の段階(最初の「確認画面」へと遷移した時点)では、$_SESSION["f"]["no"]値は生きているようです。
(4)の段階の修正するボタンを押すと消滅しているようです。

<form action="確認画面.php" method="post">
<input type="submit" name="modify" value="   修正する   ">
</form>
これをポストして、自身「確認画面.php」に再度アクセスすると、
$_SESSION["f"]["no"]が消滅しているようです。

ただ、おかしなことに、確認画面.php内のどこかに
print_r(変数); 入れてやると、一応_SESSION["f"]["no"]の値は維持されるようで、
元の入力画面へと遷移できてしまいます。
※ただ、元の入力画面に戻ったときには、_SESSION["f"]["no"]は消えているようです・・・・。
※print_rが発動したphpファイルだけが大丈夫なようです。

いろいろネットで検索をかけました。
ドメインにアンダーバーを使ってはダメだとか、session_idやname のことも調べましたが、
どうも該当している問題ではなさそうなんです。

セッションについて理解が深くない自分ですが、session_idが関連づいていない?
他のブラウザやバージョンでは問題なしだが、
IE9のみ特殊な仕様で、header("Location: " . $url);を使うとセッションを関連付けしてくれない?
ということなのかなと推測していますが。

もう自分の力量ではどうにもならず・・・・。

そもそも上記のプログラムの流れで、
他のフォームも沢山作ってきましたが、いままでこのような問題には遭遇しませんでした。
正しく稼動しています。

「入力画面」から「確認画面」へは、セッションを使って安全に遷移したいので、
他の方法をとるのは厳しいかなと・・・。

どうぞお力をお貸しください。
何卒よろしくお願いします。

投稿日時 - 2013-02-27 23:18:30

QNo.7968153

すぐに回答ほしいです

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.2

細かくは見ていませんが、session.use_only_cookies がOn でクッキーを拒否しているとか…。
いずれにしてもIE9のみというのは解せませんので、ブラウザの環境まわりでは?

投稿日時 - 2013-03-01 19:42:52

補足

回答ありがとうございます。

session.use_only_cookies = 0 

となりますのでoff設定。・・・ですよね?

php.iniは、xamppをインストしたころから殆どいらってませんので、セッションまわりもデフォルト設定です。

また、IE9の環境の問題と疑いました。

プライバシー設定等をいじりましたが、やはり変わらず・・・。

引き続き、調査を進めますので、ひらめいたことがあれば何でもご教授ください。

投稿日時 - 2013-03-01 22:13:50

お礼

真夜中に解決方法がひらめいたので書き込みします。

ようやく、この件に関して解決できました。
皆様ありがとうございます。
本当に「やられた・・・・」って感じ、開発を進めててもこの事が気になって気になって・・・ついつい原因究明に時間を使ってました。

原因は、
セッション開始時の
session_regenerate_id(true);
にありました。

こやつは、session_start();直後に呼び出して、
idを変更し、古いのを削除してくれる機能です。※自動削除はphp5.0以降
いわゆるセッション固定攻撃の防止です。

これをですね、
セッションが絡むページの全てで、
session_start();
session_regenerate_id(true);
としてしまうと、
「入力画面」>「確認画面」などのリダイレクト処理がされた場合に、新規にsession_idを作成し、古いものは消去されないという現象になってしまいます。
※セッションを引き継がないと言うこと。
しかもIE9だけがそうなります。(全ブラウザの調査はまだしていません)

で、これを回避するのは、
ログイン画面や「入力画面」などの重要なセス保存のページの次のページ(※「確認画面など」)で
session_regenerate_id(true);を入れればいいみたいなんです。
つまり、それ以外のページでは、
session_start();
のみとしておく。

このことに気づかず、こんなにはまってしまって「やられた・・・・」とあきれ果てました。
session_regenerate_id(true)
↑こやつの事がふと頭によぎり、早速ググッたてみるとピンポイントの記事を発見。


http://www.nekomanma.jp/room/php/session.php


みなさま有難うございました。

投稿日時 - 2013-03-04 05:41:12

ANo.1

経験からの当てずっぽです。

「その直後、エラーチェック関数にそのセッションを通して、通過すれば「確認画面」へリダイレクトします。」

このあたりで
header(location:~~~
の後のexit;が抜けてその後のフローでセッション消去している。

以上 あてずっぽでした。

投稿日時 - 2013-03-01 00:06:04

補足

なかなか回答をいただけない中、
ありがとうございます。
一瞬 !お! と思ったのですが、
残念なことにexit;は確実に挿入しておりました。

引き続き、色々と検証しているのですが、
やはりIE9のみ、
「header("Location: ~」
でページを遷移すると、
xampp内のtmpフォルダ(session_idが格納される)に
新たなsession_idが作成されているようです。
※一旦全部削除して、IE9でフォームを動作させると、「入力画面」で一つ作成され、さらに「確認画面」へ遷移したらもう一つ作成されます。


「入力画面」で発行されたsession_idと「確認画面」で作成されたsession_idは別物ののようで、
その為「確認画面」では、セッションが引き継がれたいない現象です。
なぜ、IE9だけこうなるのか、また、このような現象がネット上ではあまり書き込みがないのか?
※あるにはあるので、対処方法を一通り試してはいるが改善しない。

なぞが深まるばかりです。
一説には、ローカルでチェック(IE9)だとこうなるが、
レンタルサーバーにあげると正常になる・・・・
なんていう記事をみたので、今はそれに賭けるて開発を進めています。

あ・・・・どうすればいいのやら・・・。

投稿日時 - 2013-03-01 16:20:36

あなたにオススメの質問