PHPコード
DiscuzのSESSIONの仕組みを解説!
いつものようにディスカスで!
データベース内に 2 つの SESSION テーブルがあることがわかります:
1 つは pre_common_adminsession で、管理者がバックグラウンドでログインするための SESSION テーブルです。
もう 1 つは pre_common_session テーブルで、すべてのユーザーがフォアグラウンドでページを参照するときの SESSION テーブルです。
どちらのテーブルもメモリ テーブルです (メモリ テーブルの読み取りおよび書き込み速度は、MYISAM テーブルやテキスト ファイルの速度よりもはるかに高速です)。
ディスカスで!
その後、ページの閲覧時に関連関数の実行がトリガーされ、データベースの SESSION テーブルに書き込まれます。
ログイン処理を例にプログラムの実行方法を説明します。
フロントのホームページで「ログイン」をクリックするとログイン画面が表示されますので、必要事項を入力の上、送信してください。フォーム送信用の URL は次のとおりです:
1 http://ux.com/member.php?mod=logging&action=login&loginsubmit =はい&floatlogin=はい&inajax=1
データは member.php ファイルに送信され、プログラム内に次のコードが表示されます:
01 $mod = !in_array($discuz->var['mod'], $modarray) ? 'logging' : $discuz->var['mod']; //mod の値は次にロードされるものですPHPページ
02 定義('CURMODULE', $mod);
03 $modcachelist = array('register' => array('modreasons', 'stamptypeid', 'fields_required', 'fields_optional', 'ipctrl'));
04 $cachelist = 配列();
05 if(isset($modcachelist[CURMODULE])) {
06 $cachelist = $modcachelist[CURMODULE]
07 }
08 $discuz->キャッシュリスト = $キャッシュリスト
09 $discuz->init();
ランフック 10 個()
;
11 require DISCUZ_ROOT.'./source/module/member/member_'.$mod.'.php' //プログラムの組み込み操作を完了します
;
source/module/member/member_logging.php ファイルを開くと、クラスの前に次の 3 行のコードが表示されます。
$ctl_obj = 新しいロギング_ctl();
$method = 'on_'.$_G['gp_action']; // $_G['gp_action'] は、アクションの値、つまりログインと同じです
$ctl_obj->$method(); //$ctl_obj->on_login();
ログイン メソッドは、メソッドの 56 行目あたりに次の判定ステートメントがあります。
if(!submitcheck('loginsubmit', 1, $seccodecheck)) {
判定ステートメントは、訪問者が閲覧した場合、submitcheck 関数の戻り値は false であり、それを反転すると true になります。
ユーザーがログインすると、プログラムは else 部分を通過し、次の 5 行のコードが表示されます。
} その他 {
$_G['uid'] = $_G['member']['uid'] = 0;
$_G['username'] = $_G['member']['username'] = $_G['member']['password'] = '';
$result = userlogin($_G['gp_username'], $_G['gp_password'], $_G['gp_questionid'], $_G['gp_answer'], $_G['setting']['autoidselect'] ? 'auto' : $_G['gp_loginfield']); // データベースからユーザー データをクエリし、対応する情報を返します
If($result['status'] > 0) { //ステータス値は 0 より大きく、このユーザーはログインできることを示します
setloginstatus($result['member'], $_G['gp_cookietime'] ? 2592000 : 0); //ログインステータスの設定、つまり COOKIE のデータは SESSION の対応するデータですが、この関数はSESSIONの書き込み操作については責任を負いません
source/function/function_login.php の setloginstatus 関数を見てみましょう。これは通常の COOKIE 書き込み操作であるため、詳細は説明しません。
関数 setloginstatus($member, $cookietime) {
グローバル $_G;
$_G['uid'] = $member['uid']
$_G['ユーザー名'] = $メンバー['ユーザー名'];
$_G['管理者'] = $メンバー['管理者']
$_G['グループID'] = $メンバー['グループID']
$_G['フォームハッシュ'] = フォームハッシュ();
$_G['セッション']['invisible'] = getuserprofile('invisible');
$_G['メンバー'] = $メンバー
;
$_G['コア']->セッション->新しい = 1;
dsetcookie('auth', authcode("{$member['password']}t{$member['uid']}", 'ENCODE'), $cookietime, 1, true); //認証コード暗号化
dsetcookie('ログインユーザー');
dsetcookie('アクティベーション認証');
dsetcookie('pmnum');
}
この時点でログイン処理はほぼ完了していると言えますが、COOKIEをクリアしないとクライアント上に常に存在し、タイムアウトになった場合、プログラムはこのCOOKIEを破棄して書き換えると判断します。
DZX のsource/class/calss_core.php ファイルにある SESSION 操作のクラスを見てみましょう:
プログラム内の各リクエストは SESSION をロードします。これはコア クラス discuz_core の _init_session メソッドによって実行されます。このメソッドはクラスの init メソッドに配置され、クラスがロードされるたびに SESSION が自動的に書き込まれることを示します。
関数 _init_session() {
$this->session = new discuz_session() //SESSION クラスを作成します
;
If($this->init_session) {
//COOKIE からデータを読み取ります
$this->session->init($this->var['cookie']['sid'], $this->var['clientip'], $this->var['uid' ]);
$this->var['sid'] = $this->session->sid;
$this->var['session'] = $this->session->var;
// SID が等しいかどうかを判断し、複数のユーザーが同じホスト上の Web サイトにログインしており、COOKIE を書き換える必要があることを示します
If($this->var['sid'] != $this->var['cookie']['sid']) {
dsetcookie('sid', $this->var['sid'], 86400);
}
If($this->セッション->isnew) {
If(ipbanned($this->var['clientip'])) {
$ This-> session-> set ('groupid', 6);
}
If($this->session->get('groupid') == 6) {
$this->var['member']['groupid'] = 6;
sysmessage('user_banned');
}
//UID が空ではなく、SESSION を更新する必要があるか、SESSION がタイムアウトになり、ユーザーのステータスが変更され、ユーザーは再度ログインする必要があります
if($this->var['uid'] && ($this->session->isnew || ($this->session->get('lastactivity') + 600)
$this->session->set('lastactivity', TIMESTAMP);
$update = array('lastip' => $this->var['clientip'], 'lastactivity' => TIMESTAMP);If($this->セッション->isnew) {
$update['lastvisit'] = タイムスタンプ;
DB::update('common_member_status', $update, "uid='".$this->var['uid']."'");
}
}
}
SESSION を操作するクラスは discuz_session です。このクラスの 2 つのメソッドを見てみましょう:
//この関数は新しいセッションの生成を担当しますが、データベースへの書き込みは担当しません
関数 create($ip, $uid) {
//SESSION を作成し、データ挿入を実行し、ランダム関数によって 6 桁の乱数を生成します。これはセッションの一意の値です。時刻は現在時刻、sid は Cookie 内の sid です。
$this->isnew = true;
$this->var = $this->newguest;
$this->set('sid', random(6));
$this->set('uid', $uid);
$this->set('ip', $ip);
$this->set('lastactivity', time());
$this->sid = $this->var['sid'];
$this->var を返す
}
//この関数は SESSION の更新を担当します
関数 update() {
If($this->sid !== null) {
$data = daddslashes($this->var);
If($this->isnew) {
$this->削除();
DB::insert('common_session', $data, false, false, true);
DB::update('common_session', $data, "sid='$data[sid]'");
dsetcookie('sid', $this->sid, 86400);
}
}
これまでのところ、SESSION をデータベースに挿入する具体的な機能と COOKIE との接続はわかっていますが、この操作がどのようにトリガーされるかは明らかではありません。
source/function/function_core.php ファイルを開き、関数 updatesession を見つけます。この関数はセッションを更新します:
関数更新セッション($force = false) {
グローバル $_G;
静的 $updated = false
;
If(!$updated) {
$discuz = & discuz_core::instance();
foreach($discuz->session->var as $k =>$v) {
If(isset($_G['member'][$k]) && $k != 'lastactivity') {
$discuz->session->set($k, $_G['member'][$k]);
}
foreach($_G['action'] as $k => $v) {
$discuz->session->set($k, $v);
}
$discuz->session->update();
$updated = true;
}
$更新
を返します。
}
プログラムのソース コードでこの関数を検索すると、次のコードが多くのテンプレートで見つかったことがわかります:
{eval updatesession();}
この関数は、ページが参照され、SESSION がデータベースに書き込まれるときにトリガーされます。
考えを整理します:
ステップ 1: ユーザーがログインし、プログラムが COOKIE をクライアントに書き込みます。これらの COOKIE は、SID、IP、TIME などの SESSION データの一部であり、ユーザー名やパスワードなどの重要な情報は含まれません。
2 番目のステップでは、ログインに成功すると、プログラムは自動的にページを更新し、別のリクエストをサーバーに送信します。サーバーは discuz_core コア クラスをロードし、COOKIE から SESSION 関連の情報を読み取りますが、まだデータベースには書き込まれていません。 。
3 番目のステップでは、コア クラスのロードが完了し、プログラムが実行を継続し、最後にテンプレートがロードされ、updatesession 関数がトリガーされ、SESSION がデータベースに書き込まれます。
著者「pz9042」
http://www.bkjia.com/PHPjc/478664.html