Nov 12 2013

PHP のセッションが消えちゃう時にチェックすること

Version : PHP 5.4.10, MAMP 2.1.2
82804

ドットインストールの解説を観ながら自分でもユーザ登録やログインを行う PHP のプログラムを書いているのですが、 $_SESSION の値がページを遷移すると消えてなくなってしまってハマりました。
いろいろググりながら試してみたところとりあえず動くようになりました。ポイントもまとめておきます。


Pocket

ユーザ管理を行うプログラムの解説ということで、ドットインストールの「ユーザー管理をするWebサービスを作ろう (全19回)」を観ながらほぼ同じプログラムを MAMP で構築したローカル環境で動かしてみたのですが動きません。

http://dotinstall.com/lessons/sns_php_v2
ユーザー管理をするWebサービスを作ろう (全19回) – プログラミングならドットインストール

ソースにデバッグプリントを入れたりしながら調べていくと、

2行目の if 文で $_SESSION[‘token’] が消えてしまっていることが原因だとわかった。$_POST[‘token’] にはきちんとトークンが入っていてこの値は POST 直前に $_SESSION[‘token’] からコピーしたものである。つまり、両方同じ値が入っていて欲しいのだけどなぜか消えてしまう。値のコピーからここまでの間にはページの遷移しかないので、そこがアヤシイ。

 

困ったので、自分自身にググレカスと言い聞かせてググりました。が、なかなか解決しない。php.ini の設定を見なおしたり、ローカル環境ではなくサーバ環境でも試してみたけど結果は同じ。

人様の環境と自分の環境が違うのかもしれないけれど、なぜドットインストールの動画ではきちんと動いているのだろう? PHP のバージョンは確かにちょっと違う。うーむ。

で、結局 stackoverflow サイトを見たら同じような質問が載っていて、解決策を答えている人がいました。よし、上から順にやっていこうと思ったら最初の1つ目がビンゴ! あらラッキー。でも、ドットインストールのレクチャー動画ではなぜ動いているのかが未だによくわかりません。

http://stackoverflow.com/questions/17242346/php-session-lost-after-redirect
PHP session lost after redirect – Stack Overflow

ようは、session_start() を呼ぶのは <?php の直後じゃなくちゃならず、空白や余計な改行もご法度とのこと。

ドットインストールの index.php, login.php, signup.php の sessionstart 部分を

から

に変更したらあっさり動いてしまいました。違いは session_start() を <?php 直下に持ってきただけ。

 

前述の stackoverflow に書かれていた気をつけるべき点を日本語で要点だけまとめておきます。

  1. sessin_start() は<?php の直後になくてはならない。空白やタブもあってはならない。
  2. header リダイレクト後のスクリプト終了は exit(); で行うべし。session_write_close(); などもあるけど自分は exit(); で動いている。
  3. ブラウザの cookie が使用可能になっていること
  4. php.ini の register_globals が off になっていること。phpinfo() を呼んでも設定を確認できる。
  5. session を明示的に消したり空白にしていないこと。
  6. $_SESSION グローバル変数をどこかで上書きしていないこと
  7. リダイレクト先が同じドメインであること。ドメインが異なるとセッションは引き継がれない。www.aaa.com から aaa.com へのリダイレクトはセッションが引き継がれない。
  8. ファイルの拡張子が .php であること。

とのことでした。

 

Pocket

No Responses

コメントを残す