<?php
/*============================檔案說明========================================
@filename: session.class.php
@description: 資料庫儲存線上使用者session,實現線上使用者功能!
@notice: session到期時間一個小時,因為我們的網站是使用cookie(有效時間是1小時)登入。
因此我們只記錄使用者登入的時間,而不是重新整理一次更新一次
刪除資料庫中session記錄的動作發生在使用者逾時後執行這個檔案或正常退出(session_destory)
@database: database:sessions field:sessionid(char32),uid(int10),last_visit(int10)
@author: duanjianbo
@adddate 2008-8-29
=============================================================================
*/ class session { private $db; private $lasttime=3600;//逾時時間:一個小時 function session(&$db) { $this->db = &$db; session_module_name('user'); //session檔案儲存方式,這個是必須的!除非在Php.ini檔案中設定了 session_set_save_handler( array(&$this, 'open'), //在運行session_start()時執行 array(&$this, 'close'), //在指令碼執行完成或調用session_write_close() 或 session_destroy()時被執行,即在所有session操作完後被執行 array(&$this, 'read'), //在運行session_start()時執行,因為在session_start時,會去read當前session資料 array(&$this, 'write'), //此方法在指令碼結束和使用session_write_close()強制提交SESSION資料時執行 array(&$this, 'destroy'), //在運行session_destroy()時執行 array(&$this, 'gc') //執行機率由session.gc_probability 和 session.gc_divisor的值決定,時機是在open,read之後,session_start會相繼執行open,read和gc ); session_start(); //這也是必須的,開啟session,必須在session_set_save_handler後面執行 } function unserializes($data_value) { $vars = preg_split( '/([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\|/', $data_value, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE ); for ($i = 0; isset($vars[$i]); $i++) { $result[$vars[$i++]] = unserialize($vars[$i]); } return $result; } function open($path, $name) { return true; } function close() { $this->gc($this->lasttime); return true; } function read($SessionKey){ $sql = "SELECT uid FROM sessions WHERE session_id = '".$SessionKey."' limit 1"; $query =$this->db->query($sql); if($row=$this->db->fetch_array($query)){ return $row['uid']; }else{ return ""; } } function write($SessionKey,$VArray) { require_once(MRoot.DIR_WS_CLASSES .'db_mysql_class.php'); $db1=new DbCom(); // make a connection to the database... now $db1->connect(DB_SERVER, DB_SERVER_USERNAME, DB_SERVER_PASSWORD, DB_DATABASE); $db1->query("set names utf8"); $this->db=$db1; $SessionArray = addslashes($VArray); $data=$this->unserializes($VArray); $sql0 = "SELECT uid FROM sessions WHERE session_id = '".$SessionKey."' limit 1"; $query0 =$this->db->query($sql0); if($this->db->num_rows($query0)<=0){ if (isset($data['webid']) && !empty($data['webid'])) { $this->db->query("insert into `sessions` set `session_id` = '$SessionKey',uid='".$data['webid']."',last_visit='".time()."'"); } return true; }else{ /*$sql = "update `sessions` set "; if(isset($data['webid'])){ $sql .= "uid = '".$data['webid']."', " ; } $sql.="`last_visit` = null " . "where `session_id` = '$SessionKey'"; $this->db->query($sql); */ return true; } } function destroy($SessionKey) { $this->db->query("delete from `sessions` where `session_id` = '$SessionKey'"); return true; } function gc($lifetime) { $this->db->query("delete from `sessions` where unix_timestamp(now()) -`last_visit` > '".$this->lasttime."'"); return true; } } ?>
本文轉載自:http://wqss.2008.blog.163.com/blog/static/912428082011823104218806/?suggestedreading
下面是php.ini中session的配置說明:
session.save_handler = "files"
; 儲存和檢索與會話關聯的資料的處理器名字。預設為檔案("files")。
; 如果想要使用自訂的處理器(如基於資料庫的處理器),可用"user"。
; 有一個使用PostgreSQL的處理器:http://sourceforge.net/projects/phpform-ext/
session.save_path = "/tmp"
; 傳遞給儲存處理器的參數。對於files處理器,此值是建立會話資料檔案的路徑。
; Windows下預設為臨時檔案夾路徑。
; 你可以使用"N;[MODE;]/path"這樣模式定義該路徑(N是一個整數)。
; N表示使用N層深度的子目錄,而不是將所有資料檔案都儲存在一個目錄下。
; [MODE;]可選,必須使用8進位數,預設600(=384),表示每個目錄下最多儲存的會話檔案數量。
; 這是一個提高大量會話效能的好主意。
; 注意0: "N;[MODE;]/path"兩邊的雙引號不能省略。
; 注意1: [MODE;]並不會改寫進程的umask。
; 注意2: php不會自動建立這些檔案夾結構。請使用ext/session目錄下的mod_files.sh指令碼建立。
; 注意3: 如果該檔案夾可以被不安全的使用者訪問(比如預設的"/tmp"),那麼將會帶來安全性漏洞。
; 注意4: 當N>0時自動記憶體回收將會失效,具體參見下面有關垃圾搜集的部分。
session.name = "PHPSESSID"
;用在cookie裡的會話ID標識名,只能包含字母和數字。
session.auto_start = Off
; 在客戶訪問任何頁面時都自動初始化會話,預設禁止。
; 因為類定義必須在會話啟動之前被載入,所以若開啟這個選項,你就不能在會話中存放對象。
session.serialize_handler = "php"
; 用來序列化/解序列化資料的處理器,php是標準序列化/解序列化處理器。
; 另外還可以使用"php_binary"。當啟用了WDDX支援以後,將只能使用"wddx"。
session.gc_probability = 1
session.gc_divisor = 100
; 定義在每次初始化會話時,啟動記憶體回收程式的機率。
; 這個收集機率計算公式如下:session.gc_probability/session.gc_divisor
; 對會話頁面訪問越頻繁,機率就應當越小。建議值為1/1000~5000。
session.gc_maxlifetime = 1440
; 超過此參數所指的秒數後,儲存的資料將被視為'垃圾'並由記憶體回收程式清理。
; 判斷標準是最後訪問資料的時間(對於FAT檔案系統是最後重新整理資料的時間)。
; 如果多個指令碼共用同一個session.save_path目錄但session.gc_maxlifetime不同,
; 那麼將以所有session.gc_maxlifetime指令中的最小值為準。
; 如果使用多層子目錄來儲存資料檔案,記憶體回收程式不會自動啟動。
; 你必須使用一個你自己編寫的shell指令碼、cron項或者其他辦法來執行垃圾搜集。
; 比如,下面的指令碼相當於設定了"session.gc_maxlifetime=1440" (24分鐘):
; cd /path/to/sessions; find -cmin +24 | xargs rm
session.referer_check =
; 如果要求標頭中的"Referer"欄位不包含此處指定的字串則會話ID將被視為無效。
; 注意:如果要求標頭中根本不存在"Referer"欄位的話,會話ID將仍將被視為有效。
; 預設為空白,即不做檢查(全部視為有效)。
session.entropy_file = ;"/dev/urandom"
; 附加的用於建立會話ID的外部高熵值資源(檔案),
; 例如UNIX系統上的"/dev/random"或"/dev/urandom"
session.entropy_length = 0
; 從高熵值資源中讀取的位元組數(建議值:16)。
session.use_cookies = On
; 是否使用cookie在用戶端儲存會話ID
session.use_only_cookies = Off
; 是否僅僅使用cookie在用戶端儲存會話ID
; 開啟這個選項可以避免使用URL傳遞會話帶來的安全問題。
; 但是禁用Cookie的用戶端將使會話無法工作。
session.cookie_lifetime = 0
; 傳遞會話ID的Cookie有效期間(秒),0 表示僅在瀏覽器開啟期間有效。
session.cookie_path = "/"
; 傳遞會話ID的Cookie作用路徑。
session.cookie_domain =
; 傳遞會話ID的Cookie範圍。
; 預設為空白表示表示根據cookie規範產生的主機名稱。
session.cookie_secure = Off
; 是否僅僅通過安全連線(https)發送cookie。
session.cookie_httponly = Off
; 是否在cookie中添加httpOnly標誌(僅允許HTTP協議訪問),
; 這將導致用戶端指令碼(JavaScript等)無法訪問該cookie。
; 開啟該指令可以有效預防通過XSS攻擊劫持會話ID。
session.cache_limiter = "nocache"
; 設為{nocache|private|public}以指定會話頁面的緩衝控制模式,
; 或者設為空白以阻止在http應答頭中發送禁用緩衝的命令。
session.cache_expire = 180
; 指定會話頁面在用戶端cache中的有效期間限(分鐘)
; session.cache_limiter=nocache時,此處設定無效。
session.use_trans_sid = Off
; 是否使用明碼在URL中顯示SID(會話ID)。
; 預設是禁止的,因為它會給你的使用者帶來安全危險:
; 1- 使用者可能將包含有效sid的URL通過email/irc/QQ/MSN…途徑告訴給其他人。
; 2- 包含有效sid的URL可能會被儲存在公用電腦上。
; 3- 使用者可能儲存帶有固定不變sid的URL在他們的收藏夾或者瀏覽曆史紀錄裡面。
; 基於URL的會話管理總是比基於Cookie的會話管理有更多的風險,所以應當禁用。
session.bug_compat_42 = On
session.bug_compat_warn = On
; PHP4.2之前的版本有一個未註明的"BUG":
; 即使在register_globals=Off的情況下也允許初始化全域session變數,
; 如果你在PHP4.3之後的版本中使用這個特性,會顯示一條警告。
; 建議關閉該"BUG"並顯示警告。
session.hash_function = 0
; 產生SID的散列演算法。SHA-1的安全性更高一些
; 0: MD5 (128 bits)
; 1: SHA-1 (160 bits)
; 建議使用SHA-1。
session.hash_bits_per_character = 4
; 指定在SID字串中的每個字元內儲存多少bit,
; 這些位元是hash函數的運算結果。
; 4: 0-9, a-f
; 5: 0-9, a-v
; 6: 0-9, a-z, A-Z, "-", ","
; 建議值為 5
url_rewriter.tags = "a=href,area=href,frame=src,form=,fieldset="
; 此指令屬於PHP核心部分,並不屬於Session模組。
; 指定重寫哪些HTML標籤來包含SID(僅當session.use_trans_sid=On時有效)
; form和fieldset比較特殊:
; 如果你包含他們,URL重寫器將添加一個隱藏的"<input>",它包含了本應當額外追加到URL上的資訊。
; 如果要符合XHTML標準,請去掉form項並在表單欄位前後加上<fieldset>標記。
; 注意:所有合法的項都需要一個等號(即使後面沒有值)。
; 推薦值為"a=href,area=href,frame=src,input=src,form=fakeentry"。