セッションクラス
セッションクラスを使うと、サイトを閲覧中のユーザの"状態"を維持でき、ユーザのアクションを追跡できます。 セッションクラスは、各ユーザのセッションの情報をシリアライズして(オプションで暗号化して)クッキーに保管します。 また、セキュリティを高めるため、ユーザのクッキー内のセッション ID と保管されたセッション ID を照合するようにして、 セッションデータをデータベースのテーブルに保存することもできます。デフォルトでは、クッキーだけが保存されます。 データベースのオプションを利用する場合は、後述するように、セッションテーブルを作成する必要があります。
Note: セッションクラスは、PHP に組み込みのセッションを利用しません。 このクラスは、独自のセッションデータを生成し、開発者にさらなる柔軟性を提供します。
Note: 暗号化セッションを使用しない場合でも、設定ファイルで encryption key を指定しなければいけません。 第三者にセッションデータを操作されるのを防ぐためです。
セッションの初期化
セッションは通常、各ページの読込みに対してグローバルに動作します。ですので、セッションクラスは、 コントローラ のコンストラクタで 初期化 されるか、あるいは、システムで 自動読込み されるか、どちらかが必要になります。 単にクラスを初期化することが、セッションを読み込み、作成し、更新することになるので、大部分で、 セッションクラスはバックグラウンドで勝手に動作します。
セッションクラスをコントローラのコンストラクタで手動で初期化するには、次のように、$this->load->library メソッドを使います:
$this->load->library('session');
一度読み込まれると、セッションライブラリのオブジェクトは、次のようにして利用できます: $this->session
セッションはどのように動作しますか?
ページが読み込まれた時、セッションクラスによって、ユーザのセッションクッキーのデータが正しいものかどうかがチェックされます。 セッションデータが存在しない場合(あるいは、有効期限切れの場合)、新しいセッションが作成され、クッキーに保存されます。 セッションが存在する時は、セッションの情報とクッキーがアップデートされます。アップデートするたびに session_id は再生成されます。
いったん初期化したら、セッションクラスは自動的に動作するということは重要です。 上のような動作をさせるために何かをしなければならないということはありません。下で見ていきますが、セッションデータを利用して処理したり、セッションデータにデータを追加したりもできます。 しかし、セッションの読込み、書き込み、更新は自動的に行われるのです。
セッションデータとは?
セッションは、CodeIgniter に関する限りは、単に次のデータを保持している配列だといえます:
- ユーザの固有のセッション ID (これは、扱いやすいように MD5 でハッシュ計算された、非常にばらつき度合いが大きい統計的にランダムな文字列で、(規定では)5分ごとに再生成されます。)
- ユーザの IP アドレス
- ユーザのユーザエージェントデータ (ブラウザデータの文字列の最初の120文字)
- "最終アクティブ日時"。
上のデータは、クッキーに、次のようにシリアライズされた配列として保管されます:
[array]
(
'session_id' => random hash,
'ip_address' => 'string - user IP address',
'user_agent' => 'string - user agent data',
'last_activity' => timestamp
)
暗号化オプションを有効にした場合、シリアライズされた配列は、クッキーに保存される前に暗号化され、 データを高いセキュリティにし、誰かに読み取られたり置き換えられたりすることがないようにします。 暗号化についての詳しい情報は、こちらにありますが、セッションクラスは、 暗号化クラスの初期化とデータの暗号化を自動的に行います。
Note: CPU の処理負荷を減らすため、セッションクッキーは、デフォルトでは、5分ごとにのみ入れ替わります。 何度もページを更新すると、最終アクティブ日時は、クッキーが書き込まれてから5分以上経過した場合だけ更新されるのが分かると思います。 この時間は system/config/config.php ファイルの $config['sess_time_to_update'] の行をユーザ指定に変更して設定することができます。
セッションデータの読み取り
セッション配列のどんな情報も、次のメソッドで利用可能です:
$this->session->userdata('item');
ここでの item は、読み取りたい項目を示す配列のインデックスになります。 たとえば、セッションIDを読み取りたいのであれば、次のようにします:
$session_id = $this->session->userdata('session_id');
Note: このメソッドは、アクセスしようとする項目が存在しない場合、FALSE (ブール値) を返します。
ユーザ定義のセッションデータを追加する
セッション配列の便利な面は、独自のデータを追加できることで、ユーザのクッキーの中に保管されます。 なぜこのようなことを行いたいのでしょうか?次のはその一例です:
サイトに特定のユーザがログインしたとします。 いったん認証したら、ユーザ名とメールアドレスが必要になったときにデータベースクエリを発行せずにグローバルに利用できるよう、 ユーザ名とメールアドレスをセッションクッキーに保存します。
セッション配列にデータを追加するには、次のメソッドを使って、新しいデータを含む配列を渡す必要があります:
$this->session->set_userdata($array);
ここでの $array は、新しいデータの連想配列になります。以下は例です:
$newdata = array(
'username' => 'johndoe',
'email' => 'johndoe@some-site.com',
'logged_in' => TRUE
);
$this->session->set_userdata($newdata);
一度に一つの値を追加したいのであれば、set_userdata() メソッドが次の構文で、サポートされています。
$this->session->set_userdata('some_name', 'some_value');
Note: クッキーは 4KB のデータだけを保持できますので、許容量を超えないよう注意してください。 ここの暗号化処理をすると、元の文字列より長い文字列になりますので、どの程度のデータを保存したのかを把握するよう注意してください。
すべてのセッションデータを取得する
すべてのユーザデータの配列は、次のように取得することができます:
$this->session->all_userdata()
これは、次のような連想配列を返します:
Array ( [session_id] => 4a5a5dca22728fb0a84364eeb405b601 [ip_address] => 127.0.0.1 [user_agent] => Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; [last_activity] => 1303142623 )
セッションデータの削除
set_userdata() は、ただセッションにインフォメーションを追加するためだけに使用することができます。unset_userdata() は、セッションキーを渡すことによって、削除に使用することができます。例えば、もしセッションインフォメーションから 'some_name' を削除したい場合は:
$this->session->unset_userdata('some_name');
このメソッドは、削除したい項目の連想配列を渡すこともできます。
$array_items = array('username' => '', 'email' => '');
$this->session->unset_userdata($array_items);
フラッシュデータ
CodeIgniter では、"フラッシュデータ"、言い換えると、次のサーバリクエストだけで利用可能で、その後自動的に削除されるセッションデータをサポートしています。これは、非常に有用で、通知メッセージやステータスメッセージ(たとえば次のようなものです:「レコード2は削除されました」)によく利用されます。
Note: フラッシュ変数の前には、"flash_" が付加されますので、セッション名にはこのプリフィックスを使わないようにしてください。
フラッシュデータを追加するには:
$this->session->set_flashdata('item', 'value');
また、set_userdata() と同じやり方で、set_flashdata() に配列を渡すこともできます。
フラッシュデータを読み取るには:
$this->session->flashdata('item');
追加のリクエストまでフラッシュ変数を持ち越す必要が出てきた場合、keep_flashdata() メソッドを使って、そうすることができます。
$this->session->keep_flashdata('item');
セッションデータをデータベースに保存する
ユーザのクッキーの中に保管されるセッションデータの配列にはセッション ID が含まれていますが、セッションデータをデータベースに保存しているのでないなら、セッション ID を検証する方法はありません。 少しかあるいはまったくセキュリティを必要としなアプリケーション用には、セッション ID の検証は必要ありません。 しかし、セキュリティが必要なアプリケーションであれば、検証は必須です。 さもなければ、ユーザがクッキーを書き換えることにより、古いセッションをリストアできてしまいます。
セッションデータがデータベースで利用可能なとき、正しい形式のセッションがユーザのクッキーの中にあった場合は、データベースのクエリでそれを照合します。 セッション ID が不一致の場合は、セッションが破棄されます。 セッション ID は更新されることがなく、新しいセッションが作成されるときに生成されます。
セッションを記録するには、セッション保存用のデータベーステーブルをまず作成しなければなりません。 次は、セッションクラスが必要とする (MySQL 用の) 基本的な例です。:
Note: デフォルトでは、ci_sessions という名前のテーブルになりますが application/config/config.php ファイルを更新する限り、 望みどおりどんな名前も付けれらますので、テーブル名は、選んだ名前になります。データベーステーブルを作成したら、 config.php ファイルで次のようにデータベースオプションを有効にできます:
$config['sess_use_database'] = TRUE;
有効化されると、セッションクラスはセッションデータを DB に保存するようになります。
設定ファイルで次のように、テーブル名を指定するのを確認してください:
$config['sess_table_name'] = 'ci_sessions';
Note: セッションクラスには、有効期限切れのセッションをクリアする組み込みのガベージコレクションがありますので、 独自のクリア処理を書く必要はありません。
セッションの破棄
現在のセッションをクリアするには次のようにします:
$this->session->sess_destroy();
Note: このメソッドは、最後に呼び出してください。呼び出した後は、フラッシュデータも破棄されます。もし、一部の項目を破棄したい場合は、unset_userdata() を使ってください。
セッションの設定
application/config/config.php ファイルの中に、セッション関連の設定があります:
設定項目 | 初期値 | 選択肢 | 説明 |
---|---|---|---|
sess_cookie_name | ci_session | なし | セッションクッキーを保存するときの名前。 |
sess_expiration | 7200 | なし | セッションを終了させたい秒数。デフォルトでは2時間(7200秒)。有効期限がないセッションを使いたい場合は0に設定してください。 |
sess_expire_on_close | FALSE | TRUE/FALSE (ブール値) | ブラウザが閉じられたときに自動でセッションを破棄するかどうか。 |
sess_encrypt_cookie | FALSE | TRUE/FALSE (ブール値) | セッションデータを暗号化するかどうか。 |
sess_use_database | FALSE | TRUE/FALSE (ブール値) | セッションデータをデータベースに保存するかどうか。このオプションを有効にする前に、テーブルを作成する必要があります。 |
sess_table_name | ci_sessions | 正しい SQL テーブル名 | セッションデータベーステーブル名。 |
sess_time_to_update | 300 | 秒 | この項目は、セッションクラスが、どれくらい頻繁にセッションを再生成し新しいセッション ID を作成するかを設定します。 |
sess_match_ip | FALSE | TRUE/FALSE (ブール値) | セッションデータを読み取る時、ユーザの IP アドレスを照合するかどうか。 ISP によっては、IP アドレスが動的に変わるので、セッションが切れないよう FALSE に設定した方がいいかも知れないことに注意してください。 |
sess_match_useragent | TRUE | TRUE/FALSE (ブール値) | セッションデータを読み取る際に、ユーザエージェントを照合するかどうか。 |