CI フレームワーク Session.php ソース コード分析、CI フレームワーク session.php
CI のセッションはネイティブ セッションではなく、私が以前に使用したすべての Cookie ベースのセッションです。さらに、CI はユーザーの選択に従ってセッションをデータベースに保存するかどうかを設定できます。私はこの機能がとても気に入っています。 「データのフラッシュアウト」もあります。データのフラッシュ機能は次のサーバーリクエストでのみ利用可能で、その後は自動的にクリアされます。一般的な使用方法は次のとおりです:
$this->session->set_userdata('some_name', 'some_value') //セッションデータを設定します
$this->session->userdata('item') //セッションデータを取得します
$this->session->unset_userdata('some_name') //セッションデータを削除します
$this->session->sess_destroy() //セッションデータを破棄します
$this->session->set_flashdata('item', 'value') //フラッシュデータを設定します
$this->session->flashdata('item') //フラッシュデータを取得します
$this->session->keep_flashdata('item') //フラッシュデータを保持します
;
コードをコピーします コードは次のとおりです:
/**
* CI はセッションベースの Cookie です
*/
クラス CI_Session {
var $sess_encrypt_cookie = FALSE; セッションを暗号化するかどうか
;
var $sess_use_database = FALSE; //セッションをデータベースに保存するかどうか
;
var $sess_table_name = '' //セッションがデータを保存するテーブル名
;
var $sess_expiration = 7200; //セッションの有効期限
;
var $sess_expire_on_close = FALSE; //ブラウザウィンドウを閉じたときにセッションを自動的に期限切れにするかどうか
;
var $sess_match_ip = FALSE;//ユーザーのIPアドレスを通じてセッションデータを読み取るかどうか
var $sess_match_useragent = TRUE; //対応するユーザーエージェントに従ってセッションデータを読み取るかどうか。
var $sess_cookie_name = 'ci_session' //クッキー名
;
var $cookie_prefix = '' // クッキーのプレフィックス
;
var $cookie_path = '' //クッキーのパス
;
var $cookie_domain = '' // クッキーのスコープ
;
var $cookie_secure = FALSE // 安全な https プロトコルで有効かどうか
;
var $sess_time_to_update = 300; //セッション Cookie が更新される頻度
;
var $encryption_key = '' //暗号化キー
;
var $flashdata_key = 'フラッシュ';
var $time_reference = '時間';
var $gc_probability = 5 //セッションをリサイクルする機能
;
var $userdata = array() //ユーザーセッションデータ格納変数
;
var $CI; //CI スーパーハンドル
var $now // 現在時刻
パブリック関数 __construct($params = array())
{
log_message('debug', "セッション クラスが初期化されました");
// CI スーパークラスを取得します
$this->CI =& get_instance();
// 設定ファイル内の設定データを取得します
foreach (array('sess_encrypt_cookie', 'sess_use_database', 'sess_table_name', 'sess_expiration', 'sess_expire_on_close', 'sess_match_ip', 'sess_match_useragent', 'sess_cookie_name', 'cookie_path', 'cookie_domain', 'cookie_secure', to_update '、'time_reference'、'cookie_prefix'、'encryption_key') を $key) として
{
$this->$key = (isset($params[$key])) $params[$key] : $this->CI->config->item($key);
}
//Encryption_key を設定する必要があります
if ($this->encryption_key == '')
{
Show_error('Session クラスを使用するには、構成ファイルに暗号化キーを設定する必要があります。');
}
//文字列ヘルパー関数をロードします
$this->CI->load->helper('string');
// DCookie が暗号化されている場合、暗号化クラスが導入されます
if ($this->sess_encrypt_cookie == TRUE)
{
$this->CI->load->library('encrypt');
}
// セッションがデータベースに含まれている場合は、db
を導入します
if ($this->sess_use_database === TRUE かつ $this->sess_table_name != '')
{
$this->CI->load->database();
}
// 現在時刻を取得します
$this->now = $this->_get_time();
// セッションの有効期間が設定されていない場合、デフォルトは 2 年です
if ($this->sess_expiration == 0)
{
$this->sess_expiration = (60*60*24*365*2);
}
// クッキー名を取得します
$this->sess_cookie_name = $this->cookie_prefix.$this->sess_cookie_name;
// セッションが存在しない場合は、新しいセッションを作成します
if ( ! $this->sess_read())
{
$this->sess_create();
}
それ以外
{
$this->sess_update();
}
// old とマークされたフラッシュ データをフラッシュ出力します
$this->_flashdata_スイープ();
// フラッシュされた新しいデータを古いものとしてマークします。古いものとしてマークされたデータは、次のリクエストでフラッシュされます
。
$this->_flashdata_mark();
//期限切れのセッションをリサイクル/削除します
$this->_sess_gc();
log_message('debug', "セッション ルーチンは正常に実行されました");
}
// ------------------------------------------------ --------------------
/**
* セッションデータの読み取り
*/
関数sess_read()
{
// 获取セッション
$session = $this->CI->input->cookie($this->sess_cookie_name);
// セッションがありません 拜拜
if ($session === FALSE)
{
log_message('debug', 'セッション Cookie が見つかりませんでした。');
FALSE を返します;
}
// 如果加密了cookie
if ($this->sess_encrypt_cookie == TRUE)
{
$session = $this->CI->encrypt->decode($session);
}
それ以外
{
// 暗号化が使用されていないため、md5 ハッシュを確認する必要があります
$hash = substr($session, strlen($session)-32); // 最後の 32 文字を取得します
$session = substr($session, 0, strlen($session)-32);
// md5 ハッシュは一致しますか? これは、ユーザー空間でのセッションデータの操作を防ぐためです
if ($hash !== md5($session.$this->encryption_key))
{
log_message('error', 'セッション Cookie データが予期したものと一致しませんでした。これはハッキングの試みである可能性があります。');
$this->sess_destroy();
FALSE を返します;
}
}
// 反順序列化存続Cookieのセッション数組
$session = $this->_unserialize($session);
// セッションのデータ
if ( ! is_array($session) OR ! isset($session['session_id']) OR ! isset($session['ip_address']) OR ! isset($session['user_agent']) OR ! isset($session ['last_activity']))
{
$this->sess_destroy();
FALSE を返します;
}
// セッションデータ过期終了吗
if (($session['last_activity'] + $this->sess_expiration) < $this->now)
{
$this->sess_destroy();
FALSE を返します;
}
// かどうかは使用者ipに基づいてセッションデータを取得します
if ($this->sess_match_ip == TRUE AND $session['ip_address'] != $this->CI->input->ip_address())
{
$this->sess_destroy();
FALSE を返します;
}
// 否かに基づいてua来一致セッションデータ
if ($this->sess_match_useragent == TRUE AND trim($session['user_agent']) != trim(substr($this->CI->input->user_agent(), 0, 120)) )
{
$this->sess_destroy();
FALSE を返します;
}
// セッション入力が完了した場合、この方法はより安全です、当然のことながら、ダウンロード時間がかかります、就不建议了、データ库读写压力大
if ($this->sess_use_database === TRUE)
{
$this->CI->db->where('session_id', $session['session_id']);
if ($this->sess_match_ip == TRUE)
{
$this->CI->db->where('ip_address', $session['ip_address']);
}
if ($this->sess_match_useragent == TRUE)
{
$this->CI->db->where('user_agent', $session['user_agent']);
}
$query = $this->CI->db->get($this->sess_table_name);
// 検索結果はありません? 殺してください!
if ($query->num_rows() == 0)
{
$this->sess_destroy();
FALSE を返します;
}
// カスタムデータはありますか? その場合は、メインセッション配列に追加します
$row = $query->row();
if (isset($row->user_data) AND $row->user_data != '')
{
$custom_data = $this->_unserialize($row->user_data);
if (is_array($custom_data))
{
foreach ($custom_data as $key => $val)
{
$session[$key] = $val;
}
}
}
}
// セッションは有効です!
$this->userdata = $session;
unset($session);
TRUE を返します;
}
// ------------------------------------------------ --------------------
/**
* 読み取ったセッションデータを
に書き込みます
*/
関数 sess_write()
{
// 否か書き込みdb
if ($this->sess_use_database === FALSE)
{
$this->_set_cookie();
戻ります;
}
// カスタム ユーザーデータ、すぐに設定するセッション データを設定します
$custom_userdata = $this->ユーザーデータ;
$cookie_userdata = array();
// 続行する前に、処理するカスタム データがあるかどうかを判断する必要があります。
// デフォルトのインデックスを削除して、配列に何かが残っているかどうかを確認して、これを判断しましょう
// ついでにセッション データを設定します
foreach (array('session_id','ip_address','user_agent','last_activity') as $val)
{
unset($custom_userdata[$val]);
$cookie_userdata[$val] = $this->userdata[$val];
}
// カスタム データは見つかりましたか? そうでない場合は、空の配列を文字列に変換します
// 空の配列をシリアル化して DB に保存する理由がないため
if (count($custom_userdata) === 0)
{
$custom_userdata = '';
}
それ以外
{
// 保存できるようにカスタム データ配列をシリアル化します
$custom_userdata = $this->_serialize($custom_userdata);
}
// セッションを更新记录
$this->CI->db->where('session_id', $this->userdata['session_id']);
$this->CI->db->update($this->sess_table_name, array('last_activity' => $this->userdata['last_activity'], 'user_data' => $custom_userdata ));
// クッキーを書き込みます。 Cookie データ配列を
に手動で渡していることに注意してください。
// _set_cookie() 関数。通常、その関数は $this->userdata を保存しますが、
// この場合、その配列には Cookie に含めたくないカスタム データが含まれています。
$this->_set_cookie($cookie_userdata);
}
// ------------------------------------------------ --------------------
/**
* 新しいセッションを作成します
*/
関数 sess_create()
{
//保護sessid安全唯一
$sessid = '';
while (strlen($sessid)
{
$sessid .= mt_rand(0, mt_getrandmax());
}
$sessid .= $this->CI->input->ip_address();
$this->userdata = array(
「セッション ID」 => md5(uniqid($sessid, TRUE)),
「ip_address」 => $this->CI->input->ip_address(),
'user_agent' => substr($this->CI->input->user_agent(), 0, 120),
'last_activity' => $this->今、
'user_data' =>
);
// 必要に応じてデータを DB に保存します
if ($this->sess_use_database === TRUE)
{
$this->CI->db->query($this->CI->db->insert_string($this->sess_table_name, $this->userdata));
}
// クッキーを書き込みます
$this->_set_cookie();
}
// ------------------------------------------------ --------------------
/**
*セッションを更新します
*/
関数 sess_update()
{
// 默认五分钟更新
if (($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now)
{
戻ります;
}
// どのレコードを保存するかわかるように、古いセッション ID を保存します
// 必要に応じてデータベースを更新します
$old_sessid = $this->userdata['session_id'];
$new_sessid = '';
while (strlen($new_sessid)
{
$new_sessid .= mt_rand(0, mt_getrandmax());
}
// セッション ID をさらに安全にするために、ユーザーの IP と組み合わせます
$new_sessid .= $this->CI->input->ip_address();
// ハッシュに変換します
$new_sessid = md5(uniqid($new_sessid, TRUE));
// セッションデータ配列内のセッションデータを更新します
$this->userdata['session_id'] = $new_sessid;
$this->userdata['last_activity'] = $this->now;
// データベースセッションを使用していない場合は、_set_cookie() がこれを処理します
// すべてのユーザーデータを Cookie にプッシュすることによって
$cookie_data = NULL;
// データデータベース库中几率を更新します
if ($this->sess_use_database === TRUE)
{
// セッション データのみを保持するように Cookie を明示的に設定します
$cookie_data = array();
foreach (array('session_id','ip_address','user_agent','last_activity') as $val)
{
$cookie_data[$val] = $this->userdata[$val];
}
$this->CI->db->query($this->CI->db->update_string($this->sess_table_name, array('last_activity' => $this->今、 'session_id' => $new_sessid), array('session_id' => $old_sessid));
}
// 再新規書き込みセッション
$this->_set_cookie($cookie_data);
}
// ------------------------------------------------ --------------------
/**
*現在のセッションデータをすべて破棄します
*/
関数sess_destroy()
{
// セッション DB 行を強制終了します
if ($this->sess_use_database === TRUE && isset($this->userdata['session_id']))
{
$this->CI->db->where('session_id', $this->userdata['session_id']);
$this->CI->db->delete($this->sess_table_name);
}
// クッキーをキルします
setcookie(
$this->sess_cookie_name,
ラッシュを追加(serialize(array())),
($this->現在 - 31500000)、
$this->cookie_path,
$this->cookie_domain,
0
);
// セッションデータを強制終了します
$this->userdata = array();
}
// ------------------------------------------------ --------------------
/**
* セッション配列の指定された要素の値を取得します
*/
関数ユーザーデータ($item)
{
return ( ! isset($this->userdata[$item])) ? FALSE : $this->userdata[$item];
}
// ------------------------------------------------ --------------------
/**
* すべてのセッションデータを取得します
*/
関数 all_userdata()
{
$this->ユーザーデータを返す;
}
// ------------------------------------------------ --------------------
/**
* カスタムセッションデータの追加と変更
*/
関数 set_userdata($newdata = array(), $newval = '')
{
if (is_string($newdata))
{
$newdata = array($newdata => $newval);
}
//サポート数組結合方式
if (count($newdata) > 0)
{
foreach ($newdata as $key => $val)
{
$this->userdata[$key] = $val;
}
}
$this->sess_write();
}
// ------------------------------------------------ --------------------
/**
* セッション配列内の要素を削除します。
*/
関数 unset_userdata($newdata = array())
{
if (is_string($newdata))
{
$newdata = array($newdata => '');
}
if (count($newdata) > 0)
{
foreach ($newdata as $key => $val)
{
unset($this->userdata[$key]);
}
}
$this->sess_write();
}
// ------------------------------------------------ ------------------------
/**
* フラッシュデータの追加または変更のみ可能
*次のリクエストまで
*
* @access public
* @param混合
* @param 文字列
* @return void
*/
関数 set_flashdata($newdata = array(), $newval = '')
{
if (is_string($newdata))
{
$newdata = array($newdata => $newval);
}
if (count($newdata) > 0)
{
foreach ($newdata as $key => $val)
{
$flashdata_key = $this->flashdata_key.':new:'.$key;
$this->set_userdata($flashdata_key, $val);
}
}
}
// ------------------------------------------------ ------------------------
/**
* CI はフラッシュ データをサポートします。これは、セッション データが次のサーバー リクエストでのみ利用可能であることを意味し、次のリクエスト以降のリクエストを有効にしたい場合があります。 。 。
※keep_flashdata関数はフラッシュデータを継続的に保持し、次回リクエスト時にも有効となるようにする関数です
*/
関数 keep_flashdata($key)
{
// 将闪出データ标记成new
$old_flashdata_key = $this->flashdata_key.':old:'.$key;
$value = $this->userdata($old_flashdata_key);
$new_flashdata_key = $this->flashdata_key.':new:'.$key;
$this->set_userdata($new_flashdata_key, $value);
}
// ------------------------------------------------ ------------------------
/**
* フラッシュデータを取得します
*/
関数 flashdata($key)
{
$flashdata_key = $this->flashdata_key.':old:'.$key;
return $this->userdata($flashdata_key);
}
// ------------------------------------------------ ------------------------
/**
* _flashdata_sweet がデータをクリアできるように、フラッシュ データを古いものとしてマークします
*/
関数_flashdata_mark()
{
$userdata = $this->all_userdata();
foreach ($userdata as $name => $value)
{
$parts =explode(':new:', $name);
if (is_array($parts) && count($parts) === 2)
{
$new_name = $this->flashdata_key.':old:'.$parts[1];
$this->set_userdata($new_name, $value);
$this->unset_userdata($name);
}
}
}
// ------------------------------------------------ ------------------------
/**
* 古いとマークされたフラッシュデータをフラッシュします
*/
関数_flashdata_スイープ()
{
$userdata = $this->all_userdata();
foreach ($userdata as $key => $value)
{
if (strpos($key, ':old:'))
{
$this->unset_userdata($key);
}
}
}
//获取当前時刻
関数_get_time()
{
if (strto lower($this->time_reference) == 'gmt')
{
$now = time();
$time = mktime(gmdate("H", $now), gmdate("i", $now), gmdate("s", $now), gmdate("m", $now), gmdate("d" , $now), gmdate("Y", $now));
}
それ以外
{
$time = time();
}
$time を返します;
}
// ------------------------------------------------ --------------------
/**
* セッションクッキーを書き込む
*
*/
関数_set_cookie($cookie_data = NULL)
{
if (is_null($cookie_data))
{
$cookie_data = $this->ユーザーデータ;
}
// 配列化数组
$cookie_data = $this->_serialize($cookie_data);
//加密データ
if ($this->sess_encrypt_cookie == TRUE)
{
$cookie_data = $this->CI->encrypt->encode($cookie_data);
}
それ以外
{
// 暗号化が使用されていない場合は、ユーザー側の改ざんを防ぐために md5 ハッシュを提供します
$cookie_data = $cookie_data.md5($cookie_data.$this->暗号化キー);
}
//sess_expire_on_close が TRUE、浏览器关闭、セッション損失
$expire = ($this->sess_expire_on_close === TRUE) ? 0 : $this->sess_expiration + time();
// クッキーを設定します
setcookie(
$this->sess_cookie_name,
$cookie_data、
$期限切れ、
$this->cookie_path,
$this->cookie_domain,
$this->cookie_secure
);
}
// ------------------------------------------------ --------------------
/**
* シリアル化された配列
*/
関数_serialize($data)
{
if (is_array($data))
{
foreach ($data as $key => $val)
{
if (is_string($val))
{
$data[$key] = str_replace('\', '{{スラッシュ}}', $val);
}
}
}
それ以外
{
if (is_string($data))
{
$data = str_replace('\', '{{スラッシュ}}', $data);
}
}
戻りシリアル化($data);
}
// ------------------------------------------------ --------------------
/**
* 配列のデシリアライズ
*/
関数_unserialize($data)
{
$data = @unserialize(strip_slashes($data));
if (is_array($data))
{
foreach ($data as $key => $val)
{
if (is_string($val))
{
$data[$key] = str_replace('{{スラッシュ}}', '\', $val);
}
}
$data を返します;
}
return (is_string($data)) ? str_replace('{{スラッシュ}}', '\', $data) : $data;
}
// ------------------------------------------------ --------------------
/**
* データベース内の無効なセッション情報をリサイクル/削除します
*/
関数_sess_gc()
{
if ($this->sess_use_database != TRUE)
{
戻ります;
}
srand(time());
if ((rand() % 100) < $this->gc_probability)
{
$expire = $this->now - $this->sess_expiration;
$this->CI->db->where("last_activity < {$expire}");
$this->CI->db->delete($this->sess_table_name);
log_message('debug', 'セッション ガベージ コレクションが実行されました。');
}
}
}
例の html 面はモジュールファイルです、モジュールファイルも php ファイルです、直接可能です
$this->session->userdata('item');
シングルエントリモードの場合は、index.php
/**
*
**/に紹介があります
自分またはチームで開発した独自のフレームワークの場合は、それを示すものもあります
http://www.bkjia.com/PHPjc/904912.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/904912.html技術記事 CI フレームワーク Session.php ソース コード分析、ci フレームワーク session.php CI のセッションはネイティブ セッションではなく、以前に使用したすべての Cookie ベースのセッションです。さらに、CI はユーザーの選択に従って構成できます...
。