このページはPHPプロジェクトへの変更提案の日本語訳です。オリジナルは以下のURLを参照してください。 https://wiki.php.net/rfc/session-lock-ini ====== PHP RFC: session.lock, session.lazy_write 及び session.lazy_destory の導入 ====== * Version: 0.9 * Date: 2013-12-21 * Author: Yasuo Ohgaki, yohgaki@ohgaki.net * Status: Under Discussion * First Published at: http://wiki.php.net/rfc/session-lock-ini ===== 概要 ===== 提案1: セッションモジュールはデフォルトでセッションデータをロックします。ロックはセッションを利用するPHPスクリプトを直列化(シリアライズ)することによりセッションデータの完全性を保ちます。(つまり、当時一つのPHPスクリプトのみセッションデータにアクセス可能) 現在のセッションモジュールの動作はセッションデータの完全性を保ちます。しかし、スクリプト実行を直列化しアプリケーションの実行パフォーマンスを低下させます。 Memcache/Memcachedセッションセーフハンドラは、多少の完全性を犠牲にしますがロック制御のINIオプションを既に持っています。 提案2: セッションデータはデータに変更がなかった場合、必ずしもセッションデータストレージに保存される必要はありません。不必要なセッションデータの書き込みを省略することにより、全体的なシステム性能が向上します。 提案3: セッションIDが更新された場合にレースコンディションが発生する場合があります。 * スクリプトAがセッションIDを更新 * スクリプトBがサーバーに古いセッションIDでアクセス 現在のセッションモジュールは単純にセッションデータを削除します。このため、スクリプトBは古いセッションIDでサーバーにアクセスします。session.strict_mode=Onでない場合、セッションモジュールはセッションデータを攻撃者が知っているかの知れない古いIDで最初期化します。 レイジーなセッションデータ削除はこの問題を解決します。 ===== 提案 1 - session.lock ===== セッションデータのロックを制御するsession.lockを導入する。 session.lock - デフォルトでOn session.lock=Onの場合、セーブハンドラーは現在と全く同じ動作をする。 session.lock=Offの場合、セーブハンドラはどうしてもロックが必要な場合にのみセッションデータをロックする。filesセーブハンドラの場合、セッションデータの読み書き時のみロックする。 現在の動作: Open session data ----------------- ↓ ↑ Read session data | ↓ (Script execution) Locked ↓ Write session data | ↓  ↓ Close session data ------------------ session.lock=Off時の新しい動作: Open session data ↓ Read session data ← Locked ↓ (Script execution) ↓ Write session data ← Locked ↓  Close session data ===== 提案 2 - session.lazy_wirte ===== レイジーなセッションデータ書き込みを制御するsession.lazy_writeを導入する。 session.lazy_write - デフォルトはOff session.lazy_write=Offの場合, セッションモジュールは現在と全く同じ動作をする。 session.lazy_write=Onの場合、セッションジュールはセッションデータが変更された場合にのみセッションデータを保存する。 セッションデータを読み込んだ際、セッションジュールは読み込んだセッションデータのMD5ハッシュを取得する。書き込み時にはセッションデータの古いMD5ハッシュと新しいMD5ハッシュを比較し、MD5ハッシュが異なる場合にのみセッションデータを保存する。 書き込みが省略されるため、セーブハンドラは”最終更新時間”を更新できなくなる。この結果、セッションデータがタイムアウトで削除される。望まないセッションデータの有効期限切れを排除するため、”最終更新時間”を更新する新しいセーブハンドラAPIを導入する。 PS_UPDATE() session.lazy_write=Onの場合、セッションモジュールはPS_WRITE()の代わりにPS_UPDATE()を呼ぶ。 ==== filesセーブハンドラの実装 ==== filesセーブハンドラの場合、PS_OPEN()でmtimeを更新できるのでPS_UPDATE()は必要ない。filesセーブハンドラのPS_UPDATE()は単純にtrueを返す関数となる。 ===== 提案 3 - session.lazy_destroy ===== レイジーなセッションデータ削除を制御するsession.lazy_destroyを導入する。 session.lazy_destory - デフォルトでOff セッションモジュールが既に削除済み・アクセス可能を判別する為にはフラッグ/タイムスタンプが必要となる。 オプション1: タイムスタンプを $_SESSION['__SESSION_DESTROYED__'] に保存 * 利点 - 単純で高速 * 欠点 - 内部データの露出 オプション2: Introduce new save handler API that saves flag/time stamp else where. どこかにフラッグ/タイムスタンプを保存するセーブハンドラAPIを導入する。 * 利点 - 内部データ露出なし * 欠点 - 複雑で遅い ===== 後方互換性の無い変更 ===== なし ===== 提案する PHPバージョン ===== PHP 5.6 以降 ===== 既存のモジュールへの影響 ===== なし セーブハンドラモジュールの再コンパイルが必要だが、新しいリリースにはいずれにせよ再コンパイルが必要。 ===== php.ini デフォルト ===== * session.lock=On * session.lazy_write=Off * session.lazy_destroy=Off ハードコードされた設定/development/production. ===== 未解決の課題 ===== * 提案3のオプションの決定 * この提案を既存のfilesセーブハンドラに実装するか、新しいfile_extなどに実装するか ===== 投票オプション ===== Yes/No ===== パッチおよびUNITテスト ===== 未作成 ===== 実装 ===== ===== リファレンス ===== なし ===== Rejected Features =====