PHP セッションが20分ほどで勝手に消える現象に対処
PHPでwebサーバーにシステム構築する場合、必ず使用するのが「セッション」です。
なぜならば、PHPは通常のプログラムとは違い、1回実行するごとに必ず終了するからです。
つまりPHPだけでは、ログインしてもログイン中であることを覚えていないため、変わりにセッションに覚えさせるのです。
ところが今回次のようなことが起こりました。
ログインして20分ほど放置したらログアウトされてしまった。
しかも現象が出るときと出ない時がある。
プログラム上でもタイムアウトを設定していますが、今回は3時間設定していました。
20分そこそこでタイムアウトするはずないのですが、なぜタイムアウトしたのか?
なぜ再現性が低いのか?
その原因を調べたら、いろんなことがわかりました。
忘備録として記録いたします。
原因:サーバーにはセッションの有効時間が設定されていたため
注※ただし必ず削除されるわけではありません。
通常レンタルサーバーにはセッションの有効時間(session.gc_maxlifetime)が設定されています。
この有効時間が更新されずに一定期間すぎると、サーバーはセッション削除処理を実行します。
これが放置して20分そこそこでセッションが消えてしまう、直接の原因です。
具体的にはこういうことです
サーバーにはセッションの有効時間に関する設定があります。
それがこちらです。
意味は以下の通りです。
session.gc_divisor | セッション削除処理を実行する確率(分母) |
session.gc_maxlifetime | セッション有効時間(秒) |
session.gc_probability | セッション削除処理を実行する確率(分子) |
session.gc_maxlifetime が1440となっています。
これは1440秒という意味で、有効時間は24分ということです。
ちなみにsession.gc_divisor、session.gc_probabilityは何か?
というと、削除処理を実行する確率です。
上記の例だと1/1000の確率で削除処理が実行されます。
つまり放置後24分経過すると、千分の1の確率でセッションが削除されるということです。
だから現象の再現性が低かったのです。
セッションの有効時間を延長は延長できます
放置後20分そこそこでセッションが消えてしまうならば、その時間を延ばせばよいと考えました。
そこで次のように設定しました。
session.gc_maxlifetimeを1440秒(24分)→14400秒(240分/4時間)に変更しました。
この設定で20分そこそこ放置で、セッション削除現象は発生しなくなりました。
セッション有効時間(session.gc_maxlifetime)の伸ばし方
php.ini、.htaccess、PHP直接記述で対応できます。
以下にその記述方法を記載します。
php.iniで変更する場合
php.iniに次のように記述すればOKです。
時間は14400と記述していますが、好みの時間設定でOKです。
1 |
session.cookie_lifetime = 14400 |
.htaccessで変更する場合
php.iniが変更できない場合は、.htaccessで変更します。
時間は14400と記述していますが、好みの時間設定でOKです
1 |
php_value session.gc_maxlifetime 14400 |
PHPで直接記述する場合
php.iniも.htaccessもダメな場合は、phpに直接記述します。
※セッションスタートする前に記述する必要があります。
1 |
ini_set( "session.gc_maxlifetime", 300 ); |
今回はレンタルサーバーでしたが「専有サーバー」であったため、セッション有効時間を延ばすだけでOKでした。
だた、色々調べてみると有効時間を延ばすだけでは現象が直らない事例があることがわかりました。
共有サーバーではどうなるのか?
ということについても調べてみましたので、以下に記載いたします。
共有サーバーでセッション有効時間を延ばしてもセッション削除が発生する理屈
共有サーバーの場合、セッションを管理するフォルダを他の契約者と共同で使うことになります。
つまり、自分のセッション有効時間を伸ばしても、他の契約者のPHPセッション削除処理が実行されたタイミングでセッションが消える可能性があるということです。
セッション削除処理は起動されたら削除されます。
自分のセッション有効時間を4時間にしても、他の契約者が24分のままならば、他の契約者が24分放置でセッション削除処理が実行されることになります。
この場合、自分のセッション有効時間を延ばしても無意味になります。
専有サーバーならば、このようなことはありませんが、共有サーバーならばあり得ることなのです。
なので、他の利用者の影響を受けないようにする必要があります。
自分専用のセッションフォルダを作ればOKです
他の利用者の影響を受けないようにするには、セッションフォルダを「共通フォルダ」→「独自フォルダ」に変更すればよいのです。
自分専用セッションフォルダの作り方
自分専用のセッションフォルダは、次のような手順で作ります。
- 独自フォルダを作る
- セッションフォルダのパスを変更する
(1)独自フォルダを作る
FTP等で独自フォルダを作成します。
ブラウザ等から見えない位置(非表示フォルダエリア)に作成します。
例えばさくらサーバーの場合は次のようにします。
契約者名:sample
契約者ドメイン:sample.sakura.ne.jp
独自セッションフォルダ名(任意の名称でOK): session_file
/home/sample/にsession_fileフォルダを作る
(/home/sample/session_file/フォルダができます。)
HTMLを設置する場所が「/home/sample/www/」フォルダであるため、ブラウザ等からは閲覧できない位置にフォルダを作成します。
(2)セッションフォルダのパスを変更
セッションフォルダの場所を変更するには、php.ini、.htaccess、php直接記述のいずれかで変更します。
前提(以下の場所に独自セッションフォルダがあるものとします)
/home/sample/session_file
php.iniで変更する場合
php.iniに次の記述を追加します。
※フォルダ名はサーバーによって異なります。正しいフォルダ名はお使いのサーバーの仕様をご確認ください。
1 |
session.save_path = "/home/sample/session_file"; |
.htaccessで変更する場合
.htaccessで変更する場合は次の記述を追加します。
※フォルダ名はサーバーによって異なります。正しいフォルダ名はお使いのサーバーの仕様をご確認ください。
1 |
php_value session.save_path "/home/sample/session_file" |
.phpで直接記述する場合
PHPで直接記述する場合は次のように記述します。
セッションスタート前に記述する必要があります。
※フォルダ名はサーバーによって異なります。正しいフォルダ名はお使いのサーバーの仕様をご確認ください。
1 |
session_save_path("/home/sample/session_file"); |
セッションフォルダを変える場合には注意が必要です
独自フォルダに保存したセッションファイルは、サーバーによってはうまく消えずに残り続ける可能性があります。
つまりごみセッションファイルが消えずに増え続ける可能性があるということです。
その場合はCRON等を使用して、定期的に強制削除されるようにする必要があります。
リスクがあることを認識したうえで作業することが求められます。
セッションの設定は変えないに越したことはありませんが、設定を変える場合は慎重に
おそらくこの記事を読まれておられる方は、プログラムやサーバーに対して知識のある方だと思います。
もし「理屈がよくわからない」という場合は、サーバーの設定変更はやらないほうが無難です。
なぜならば、重大な問題を引き起こす可能性があるためです。
サーバーの設定を変更する場合は、他の影響も考慮し慎重に作業することが肝要です。
本記事がお役に立てば幸いです。