XCVI. セッション処理関数(session)

導入

PHPのセッションサポート機能は、複数回のアクセスを通じて特定のデー タを保持する手段を実現するものです。これにより、よりカスタマイズさ れたアプリケーションを構築し、自分の Web サイトのアピール度を増加 させることが可能となります。

Web サイトの訪問者にはセッションIDというセッションIDと呼ばれるユニークなIDが割りつけられ ます。このIDは、ユーザー側にクッキーとして保存するか、または、URL に埋め込みます。

セッションサポート機能により、任意の数の変数をリクエスト間で受けわたせる ようになります。来訪者がサイトにアクセスした際、 PHP は特定のセッションIDがリクエストとともに送信されているかどうかを ( session.auto_startが1の場合は)自動的に、または (session_start() により明示的な、あるいは session_register() により暗黙の) 要求を受けて確認します。 このIDが送信されている場合には、以前保存された変数が再現されます。

注意

session.auto_startをonとした場合、 オブジェクトをセッション変数に代入することができなくなります。 これは、セッションにおいてオブジェクトを再現するためには、 セッション開始前にクラス定義がロードされている必要があるためです。

全ての登録された変数は、リクエストが終了した後に、シリアル化されます。 未定義の登録変数は、未定義としてマーク付けされます。 これらの変数は、後でユーザーが定義しない限り、以降のアクセスにおいて セッションモジュールにより定義されません。

注意: セッション処理機能は、PHP 4.0 でサポートされました。

注意: セッションを処理している時、 session_register()関数を使用するか スーパーグローバル配列$_SESSIONへ新しいキーを 追加することにより変数が登録されるまで、セッションのレコードは作 成されないことに注意して下さい。これは、セッションが session_start()関数により開始されている場合で も真です。

セッションとセキュリティ

外部リンク: Session fixation

セッションモジュールは、セッションに保存した情報を見ることができる のがそのセッションを作成したユーザーだけであることを保証することが できません。セッションの完全性を積極的に守るには、そのセッションに 紐づく値に応じた追加措置が必要です。

セッションに運ばれるデータの重要性を評価し、必要な保護策を講じて 下さい。これには通常、お金があかり、ユーザの利便性を損なうことに なります。例えば、簡単な社会工学的な策略からユーザを守るためには、 session.use_only_cookiesを有効にして下さい。 この場合、ユーザ側でクッキーが常に有効となっている必要があり ます。そうでない場合、セッションは動作しません。

存在するセッションIDが第三者に洩れる手順は何種類かあります。 洩れたセッションIDにより、第三者が特定のIDに関連する全てのリソー スにアクセスできるようになります。まず、セッションIDがURLにより伝 送される場合です。外部サイトにリンクを張っている場合、外部サイト のreferrerログにセッションIDを含むURLが保存される可能性があります。 第二に、よりアクティブな攻撃者がネットワークのトラフィックをモニ ターしている可能性があります。セッションIDが暗号化されていない場 合、セッションIDはネットワーク上を平文テキストで伝送されます。 解決策はサーバ上にSSLを実装し、ユーザにSSLを必ず使用させることです。

要件

これらの関数は、標準モジュールの一部と して利用可能であり、常に使用できます。

注意: オプションで、Ralf S. Engelschallにより開発されたセッションの保 存用の共有メモリ(mm)を使用することも可能です。 mmをダウンロードし、インストールす ることができます。このオプションは、Windowsプラットフォームでは 利用できません。mm用セッション保存モジュールは同一セッションのロッ クに問題があるため、同時アクセスを保証することはできません。 ファイルにセッションを保存するためには、 (Solaris/LinuxまたはBSD上の/dev/md)ファイルシステムに 共有メモリを使用するためにより適当でしょう。

インストール手順

PHPのセッションサポートはデフォルトで有効となっています セッションサポートを有効にしてPHPを構築したくない場合には、 configureにオプション--disable-sessionを指定する必要があります。 セッション記憶領域として共有メモリ(mm)を使用するには、PHPのconfigure に--with-mm[=DIR]を指定します。

Windows版のPHPには この拡張モジュールのサポートが組み込まれています。これらの関数を使用 するために拡張モジュールを追加でロードする必要はありません。

注意: デフォルトでは、特定のセッションのすべての情報は session.save_path INIオプションで指定されたディレクトリに生成される ファイルに保存されます。 結びついている情報に関わらずセッション毎にひとつのファイルが生成されます。 セッションが開始され(ファイルが生成される)しかし何の情報も そのファイルに書き込まれない場合もあります(サイズがゼロのファイルが残る)。 この振る舞いはファイルシステムを使っていることによる副作用であり、 カスタムセッションハンドラ(例:データベースを使ったもの)を 使う場合には何の情報も持たないセッションについて追跡しないように することは可能です。

実行用の設定

これらの関数の動作は、php.iniの設定により変化します。

表 1. セッションの設定オプション

名前デフォルト変更の可否
session.save_path"/tmp"PHP_INI_ALL
session.name"PHPSESSID"PHP_INI_ALL
session.save_handler"files"PHP_INI_ALL
session.auto_start"0"PHP_INI_ALL
session.gc_probability"1"PHP_INI_ALL
session.gc_divisor"100"PHP_INI_ALL
session.gc_maxlifetime"1440"PHP_INI_ALL
session.serialize_handler"php"PHP_INI_ALL
session.cookie_lifetime"0"PHP_INI_ALL
session.cookie_path"/"PHP_INI_ALL
session.cookie_domain""PHP_INI_ALL
session.cookie_secure""PHP_INI_ALL
session.use_cookies"1"PHP_INI_ALL
session.use_only_cookies"0"PHP_INI_ALL
session.referer_check""PHP_INI_ALL
session.entropy_file""PHP_INI_ALL
session.entropy_length"0"PHP_INI_ALL
session.cache_limiter"nocache"PHP_INI_ALL
session.cache_expire"180"PHP_INI_ALL
session.use_trans_sid"0"PHP_INI_SYSTEM|PHP_INI_PERDIR
url_rewriter.tags"a=href,area=href,frame=src,input=src,form=fakeentry"PHP_INI_ALL
PHP_INI_* 定数の詳細と定義については、 ini_set()を参照して下さい。

セッション管理システムは、php.iniファイルに記述可能な多くの設定オ プションをサポートします。以下に概要を示します。

session.save_handler string

session.save_handler は、セッションに関連す るデータの保存および取得に使用されるハンドル名を定義します。デ フォルトは、filesです。 session_set_save_handler()も参照して下さい。

session.save_path string

session.save_path は、保存ハンドラに渡される 引数を定義します。デフォルトのファイルハンドラを選択した場合、 ファイルが作成される場所のパスになります。デフォルトは、 /tmp です。 session.save_pathのパスの深さが2より大きい場 合、ガーベッジコレクションは行われません。 session_save_path()も参照して下さい。

オプションの引数としてN(数値)を指定できます。 これはセッションファイルを分散して保存する際に ディレクトリ階層レベルを決定します。 例えば、'5;/tmp'とすると /tmp/4/b/1/e/3/sess_4b1e384ad74619bd212e236e52a5a174If という位置にセッションファイルを生成します。 Nを使用するには、これらすべてのディレクトリが 事前に作成されている必要があります。 そのためのシェルスクリプトがext/sessionmod_files.shというファイル名であります。 また、0以上のNが指定されている場合には自動ガーベッジコレクション が機能しないことに注意して下さい。詳細は php.ini を見てください。 また、Nを指定する場合は、 session.save_pathを"quotes"で囲う必要があります。 なぜならセパレータ(;) は php.ini ではコメントとしても利用されているからです。

警告

この設定を/tmp (デフォルト)のようにどこか らでも読み込み可能なディレクトリのままにしている場合、サーバ上 の他のユーザがこのディレクトリのファイルのリストを取得すること により、セッションをハイジャックをすることが可能となります。

注意: WindowsユーザがPHPのsession関数を使用するためには、この変数を変 更する必要があります。c:/tempのような有効 なパスを指定するようにして下さい。

session.name string

session.name はセッション名を指定し、 クッキー名として使用されます。 アルファベット文字のみで指定する必要があります。 デフォルトは、PHPSESSID です。 session_name()も参照して下さい。

session.auto_start boolean

session.auto_start はリクエスト開始時に セッションモジュールがセッションを自動的に開始するかどうかを 指定します。デフォルトは、0(無効)です。

session.serialize_handler string

session.serialize_handler は、シリアル化また はシリアル化データを復元するために使用されるハンドラの名前を定 義します。現在、( phpという名前の)PHP 内部 フォーマットおよび(wddxという名前の)WDDX が サポートされています。WDDXは、PHP がWDDX サポート を有効にしてコンパイル されている場合のみ使用可能です。デフォルトは、 php です。

session.gc_probability integer

session.gc_probabilitysession.gc_divisorの組み合わせでgc (ガーベッジコレクション)ルーチンの始動を制御します。 デフォルトは、1 です。 詳細はsession.gc_divisor をご覧ください

session.gc_divisor integer

session.gc_divisorsession.gc_probabilityの組み合わせで すべてのセッションの初期化過程でgc(ガーベッジコネクション)プロセス も始動する確率を制御します。確率は gc_probability/gc_divisor で計算されます。例えば、1/100は各リクエスト毎に1%の確率でGCプロセスが 始動します。 session.gc_divisorのデフォルトは100です。

session.gc_maxlifetime integer

session.gc_maxlifetime は、データが'ごみ'と みなされ、消去されるまでの秒数を指定します。

注意: デフォルトのファイルに基づくセッションハンドラを使用している場 合、使用するファイルシステムは、アクセス時間(atime)を記録できる 必要があります。Windows FATはこれができないため、 FATファイルシステムまたはatimeの記録ができない他のファイルシス テムで問題を発生した場合は、セッションのガベージコレクト処理を 行う他の手段を用意する必要があります。 PHP4.2.3以降、atimeの代わりにmtime(更新時刻)が使用されます。 このため、atimeが利用できないファイルシステムでの問題は無くなりました。

session.referer_check string

session.referer_check には、HTTP Referer に おいて確認を行う文字列を指定します。Refererがクライアントにより 送信されており、かつ、指定した文字列が見付からない場合、埋め込 まれたセッションIDは無効となります。デフォルトは空の文字列です。

session.entropy_file string

session.entropy_file は、 セッションIDを作成する際の別のエントロピソースとして使用する 外部リソースへのパスを指定します。 例としては、多くの UNIX で利用可能な /dev/random または /dev/urandom があげられます。

session.entropy_length integer

session.entropy_length は、前記のファイルから 読みこむバイト数を指定します。デフォルトは、0 (無効)です。

session.use_cookies boolean

session.use_cookiesによりクライアント側にセッ ションIDを保存する際にクッキーを使用するかどうかを指定します。デ フォルトは1 (有効)です。

session.use_only_cookies boolean

session.use_only_cookiesは、 このモジュールがクライアント側へのセッションIDの保存に Cookieのみを使用することを指 定します。デフォルトは、0 (無効、下位互換性の ため)です。この設定を有効にすることにより、セッションIDをURLに埋 め込む攻撃を防ぐことができます。この設定は、 PHP 4.3.0で追加されました。

session.cookie_lifetime integer

session.cookie_lifetimeは、ブラウザに送信す るクッキーの有効期間を秒単位で指定します。値0は、"ブラウザを閉じ るまで"を意味します。デフォルトは、0です。 session_get_cookie_params()および session_set_cookie_params()も参照して下さい。

session.cookie_path string

session.cookie_pathによりsession_cokkieで設 定するパスを指定します。デフォルトは/です。 session_get_cookie_params()および session_set_cookie_params()も参照して下さい。

session.cookie_domain string

session.cookie_domainによりsession_cookieで 指定するドメインを指定します。デフォルトでは指定されません。 session_get_cookie_params()および session_set_cookie_params()も参照して下さい。

session.cookie_secure boolean

session.cookie_secureは、 セキュアな接続を通じてのみCookieを送信できるかどうかを指定します。 デフォルトは、offです。 この設定は、PHP 4.0.4で追加されました。 session_get_cookie_params()および session_set_cookie_params()も参照して下さい。

session.cache_limiter string

session.cache_limiterにより セッションページにおけるキャッシュ制御の方法 (none/nocache/private/private_no_expire/public) を指定します。デフォルトは、nocacheです。 session_cache_limiter()も参照して下さい。

session.cache_expire integer

session.cache_expireによりキャッシュされた セッションページの有効期間を分単位で指定します。 このオプションは、nocacheリミッタに関しては効果がありません。 デフォルトは、180です。 session_cache_expire()も参照して下さい。

session.use_trans_sid boolean

session.use_trans_sidは、透過的なセッション IDの付加をするかどうかを指定します。 デフォルトは、0(無効)です。

注意: PHP 4.1.2より前のバージョンでは、このオプションは --enable-trans-sidにより コンパイル時に有効とされていました。 PHP 4.2.0以降、trans-sid機能は常にコンパイルされます。

URLに基づくセッション管理は、Cookieに基づくセッション管理と比べ てセキュリティリスクが大きくなります。例えば、ユーザは、emailに より友人にアクティブなセッションIDを含むURLを送信する可能性があ り、また、ユーザは自分のブックマークにセッションIDを含むURLを保 存し、常に同じセッションIDで使用するサイトにアクセスする可能性 があります。

session.bug_compat_42 boolean

PHP versions 4.2.0 and lower have an undocumented feature/bug that allows you to to initialize a session variable in the global scope, albeit register_globals is disabled. PHP 4.3.0 and later will warn you, if this feature is used, and if session.bug_compat_warn is also enabled.

session.bug_compat_warn boolean

PHP versions 4.2.0 and lower have an undocumented feature/bug that allows you to to initialize a session variable in the global scope, albeit register_globals is disabled. PHP 4.3.0 and later will warn you, if this feature is used by enabling both session.bug_compat_42 and session.bug_compat_warn.

session.hash_function integer

session.hash_function allows you to specify the hash algorithm used to generate the session IDs. '0' means MD5 (128 bits) and '1' means SHA-1 (160 bits).

注意: This was introduced in PHP 5.

session.hash_bits_per_character integer

session.hash_bits_per_character allows you to define how many bits are stored in each character when converting the binary hash data to something readable. The possible values are '4' (0-9, a-f), '5' (0-9, a-v), and '6' (0-9, a-z, A-Z, "-", ",").

注意: This was introduced in PHP 5.

url_rewriter.tags string

url_rewriter.tagsは、透過的なセッションIDの 付加機能が有効となった場合に、セッションIDを含めるために書き換 えられるHTMLタグを指定します。デフォルトは、 a=href,area=href,frame=src,input=src,form=fakeentry です。

注意: XHTML に適合させたい場合には form エントリは削除し、 formフィールドの前後に<fieldset> タグを使ってください。

track_varsおよび register_globals 設定はセッション変数の保存および回復方法に影響を与えます。

注意: PHP 4.0.3以降、track_vars は常 にonとなっています。

リソース型

この拡張モジュールはリソース型を全く定義し ません。

定義済みの定数

これらの定数は、この拡張モジュールで定義されており、 この拡張モジュールがPHP内部にコンパイルされているか実行時に動的にロー ドされるかのどちらかの場合のみ使用可能です。

SID (string)

"name=ID"形式でセッション名とセッションIDを格納している定数

注意: PHP 4.1.0以降、$_SESSIONは、 $_POST, $_GET, $_REQUEST等のようにグローバル変数として利用可 能です。$HTTP_SESSION_VARSと異なり、 $_SESSIONは常にグローバルです。そこで、 global$_SESSIONの場合は不要です。 このドキュメントでは、$_SESSION をあらゆる場 所で使用していることに注意して下さい。もし前者を使用したい場合に は、$_SESSION$HTTP_SESSION_VARSで置き換えることができます。 また、$_SESSIONを使用する前に session_start() を用いてセッションを開始して おく必要があることに注意して下さい。

連想配列$_SESSIONのキーは、PHPの通常の変数名 と同じ制限があります。すなわち、数字で始まることはできず、文字ま たはアンダースコアで始まる必要があります。 詳細については、本マニュアルの 変数の節を参照して下さ い。

register_globals が無効の場合、グローバル連想配列$_SESSIONのメ ンバーのみがセッション変数として登録されます。 回復されたセッション変数は、配列$_SESSIONでの み利用可能です。

セキュリティとコードの可読性のために$_SESSION (またはPHP 4.0.6以前は$HTTP_SESSION_VARS)の使用 が推奨されます。$_SESSIONの場合、 session_register(), session_unregister(), session_is_registered()は不要です。ユーザは、 通常の変数と同様にセッション変数にアクセス可能 です。

例 1. $_SESSIONで変数を登録

<?php
session_start
();
// PHP 4.0.6以前の場合は$HTTP_SESSION_VARSを使用して下さい
if (!isset($_SESSION['count'])) {
    
$_SESSION['count'] = 0;
} else {
    
$_SESSION['count']++;
}
?>

例 2. register_globals が無効な場合に、$_SESSIONに登録されている変 数の登録を解除する

<?php
session_start
();
// PHP 4.0.6とそれ以前では$HTTP_SESSION_VARSを使用して下さい
unset($_SESSION['count']);
?>

例 3. register_globals が有効な場合に、$_SESSIONを用いて登録した後、 変数の登録を解除する

<?php
session_start
();
// PHP 4.3以降では、前の例のような簡単な手法も使用できます
session_unregister('count');
?>

register_globals が有効な場合、全てのグローバル変数はセッション変数として登録するこ とが可能で、セッション変数は対応するグローバル変数として回復されま す。PHPは、どのグローバル変数がセッション変数として登録されるのか を知る必要があるため、ユーザは、変数を session_register()関数で登録する必要がありま す。しかし、$_SESSIONの場合は、エントリを設定 するだけでこれを行う必要はありません。

注意

$_SESSIONを使用し、register_globals を無効とする場合、自分のスクリプトをPHP 4.2より以前のバージョン で動作させたい場合は、 session_register(), session_is_registered(), session_unregister()を使用しないで下さい。 PHP 4.3以降ではこれらの関数を使用することができます。

register_globalsを 有効にしている場合は、 session_unregister()を使用する必要があります。 これは、シリアル化されたセッションデータが戻される時にセッション 変数がグローバル変数として登録されるためです。 セキュリティ面と性能面の双方よりregister_globals を無効とすることが推奨されています。

例 4. register_globals が有効な場合に、変数を登録する

<?php
if (! isset($_SESSION['count'])) {
    
$_SESSION['count'] = 1;
} else {
    
$_SESSION['count']++;
}
?>

register_globals が有効な場合、グローバル変数と$_SESSIONの エントリは、前のセッションインスタンスで登録されたセッション変数 の同じ値を参照することになります。

PHP 4.2.3とそれ以前のバージョンのみに関係する問題があります。 session_register()により新しいセッショ ン変数を登録する場合、グローバルスコープのエントリと $_SESSIONのエントリは、次の session_start()まで同じ値へのリファレンスとは なりません。 すなわち、グローバル変数への修正は、$_SESSION のエントリには反映されません。PHP 4.3では修正されています。

セッションIDの受渡し

セッションIDの通知を行うためには次の二つの方法があります。

  • Cookie

  • URLパラメータ

sessionモジュールは、両方の方法をサポートします。 Cookieは最適ですが、(クライアントがCookieを受け入れない可能性が あるため)信頼性がなく、これに依存することができません。2番目の方 法は、セッションIDを直接URLに埋め込みます。

PHPには、透過的にリンクを変換する機能を有しています。 PHP 4.2以降を使用していない場合、PHP構築時にこの機能を有効にして おく必要があります。UNIX環境では、 --enable-trans-sidをconfigureに指定して 下さい。この構築オプションと実行時オプション session.use_trans_sidが有効な場合、 相対URIは自動的にセッションIDを含むように変換されます。

注意: arg_separator.output php.ini ディレクティブにより、引数セパレータをカスタマイズする ことができます。XHTMLに完全準拠するためには、ここに &amp; を指定して下さい。

もしくは、常に定義されている定数SIDを使用する こともできます。クライアントが適当なセッションクッキーを送信しな かった場合、この定数はsession_name=session_id の形式となります。他方、送信された場合には、この定数は空の文字列 に展開されます。このため、この定数を無条件にURLに埋め込むことがで きます。

次の例は、変数の登録法および SID を用いて他のページに正しくリンク する方法のデモです。

例 5. 単一のユーザーに関するヒット数を数える

<?php
if (!session_is_registered('count')) {
    
session_register('count');
    
$count = 1;
} else {
    
$count++;
}
?>

こんにちは、あなたがこのページに来たのは<?php echo $count; ?>回目ですね。 <p>

続けるには、<A HREF="nextpage.php?<?php echo strip_tags (SID)?>">ここをクリック</A>して下さい。

XSSに関係する攻撃を防止するためにSIDを出力する際に、 strip_tags()を使用します。

PHPをコンパイルする際に --enable-trans-sid を使用した場合、 上の例のように SID を出力する必要はありません。

注意: 相対URLでないURLは外部サイトを指していると仮定され、SIDが追加 されません。これは、SIDを外部のサーバに開示することはセキュリティ 上のリスクとなる可農政があるためです。

カスタムセッションハンドラ

セッション情報をデータベースに保存する機能か他の保存法を実装する には、一連のユーザレベルの保存関数を作成し、 session_set_save_handler()を使用する必要があり ます。

目次
session_cache_expire -- カレントのキャッシュの有効期限を返す
session_cache_limiter -- カレントのキャッシュリミッタを取得または設定する
session_commit -- Alias of session_write_close()
session_decode -- 文字列からセッションデータをデコードする
session_destroy -- セッションに登録されたデータを全て破棄する
session_encode --  現在のセッションデータを文字列としてエンコードする
session_get_cookie_params --  セッションクッキーのパラメータを得る
session_id -- カレントのセッションIDを取得または設定する
session_is_registered --  変数がセッションに登録されているかどうかを調べる
session_module_name -- 現在のセッションモジュールを取得または設定する
session_name -- カレントのセッション名を取得または設定する
session_regenerate_id --  現在のセッションIDを新しく生成したものと置き換える
session_register -- 現在のセッションに1つ以上の変数を登録する
session_save_path --  現在のセッションデータ保存パスを取得または設定する
session_set_cookie_params --  セッションクッキーパラメータを設定する
session_set_save_handler --  ユーザ定義のセッション保存関数を設定する
session_start -- セッションデータを初期化する
session_unregister -- 現在のセッションから変数の登録を削除する
session_unset --  全てのセッション変数を開放する
session_write_close -- セッションデータを書き込んでセッションを終了する