ฉันเคยเขียนบทความสองบทความก่อนหน้านี้ "การปรับแต่งเซสชัน (2) - การบันทึกฐานข้อมูล" และ "เหตุใดฉันจึงไม่ใช้เซสชัน"
แต่ต่อมาพบว่ามีปัญหา การประมวลผลแบบเดิมแทบไม่มีประโยชน์ในทางปฏิบัติ และการรีไซเคิลเซสชันจะต้องได้รับการจัดการแยกกัน หลังใช้งานฐานข้อมูลบ่อยครั้งทำให้เกิดปัญหาด้านประสิทธิภาพอย่างมาก
หลังจากพิจารณาอย่างรอบคอบในช่วงสองวันที่ผ่านมา ก็ได้มีแผนคร่าวๆ แต่ไม่มีการทดสอบเฉพาะเจาะจงและละเอียด
1. รวมการประมวลผลเซสชันและสถิติเข้าด้วยกัน มีการบันทึกผู้เยี่ยมชมด้วย
2. ใช้ฐานข้อมูลและคุกกี้โดยสมบูรณ์เพื่อจำลองฟังก์ชันเซสชัน
3. การดำเนินการของผู้ใช้ในเซสชันควรเสร็จสิ้นในคำสั่ง SQL เดียวให้มากที่สุด เมื่อไม่ต้องการเซสชัน จะไม่มีการสืบค้นมากกว่าหนึ่งรายการอย่างแน่นอน
4. เพื่อประสิทธิภาพ การรีไซเคิลเซสชันจะไม่ถูกรวมเข้าด้วยกัน แต่มีอินเทอร์เฟซให้ไว้และสามารถเรียกให้นำไปใช้ได้
รหัสนี้ให้ไว้ชั่วคราวโดยไม่มีคำอธิบายโดยละเอียด
ฐานข้อมูล SQL
สร้างตาราง `******_session` (
`sid` ถ่าน (32) ไม่เป็นโมฆะ
`uid` int(10) ไม่เป็นโมฆะ
`ชื่อผู้ใช้` ถ่าน (32) ไม่เป็นโมฆะ
`ชื่อผู้ใช้` Tinyint (1) ไม่เป็นโมฆะ
`activetime` int (10) ไม่เป็นโมฆะ
`หมดอายุ` int (10) ไม่เป็นโมฆะ
`ip` ถ่าน (15) ไม่เป็นโมฆะ
`url` ถ่าน (80) ไม่เป็นโมฆะ
`ค่า` ถ่าน (255) ไม่เป็นโมฆะ
คีย์หลัก (`sid`)
) ENGINE=หน่วยความจำเริ่มต้น CHARSET=utf8;
รหัส PHP
-
เซสชั่นชั้นเรียน{
ส่วนตัว $_sessionPrex= '';//คำนำหน้าเซสชัน
ส่วนตัว $_time = '';//เวลาปัจจุบัน
ส่วนตัว $_model = null; // รูปแบบการดำเนินการฐานข้อมูล
ส่วนตัว $_expiry = 1200;//เวลาที่ถูกต้องของเซสชัน
$_domain ส่วนตัว = '';//ขอบเขตเซสชัน
ป้องกัน $isNew = 0;//กำหนดการดำเนินการดำเนินการ 0 อัปเดต 1 เพิ่มขึ้น
ป้องกัน $session = array();//บันทึกเซสชันที่สอดคล้องกัน
ฟังก์ชั่นสาธารณะ __construct($options){
$นี่->_setOptions($ตัวเลือก);
ถ้า(ว่าง($นี่->_เวลา))$นี่->_เวลา = เวลา();
$this->session['activetime'] = $this->_time;
-
ฟังก์ชั่นสาธารณะเริ่มต้น () {
$นี่->_getSid();
-
ชุดฟังก์ชันสาธารณะ($key,$value){
if(in_array($key,array('uid','username','usertype','url','expiry'))){
ถ้า($key == 'หมดอายุ'){
$this->_setCookie($this->_sessionPrex.'_sid',$this->session['sid'],$value);
$this->_setCookie($this->_sessionPrex.'_uid',$this->session['uid'],$value);
-
$this->session[$key] = $value;
}อื่น{
$other = $this->session['value'];
$อื่นๆ[$key] = $value;
$this->session['value'] = $other;
-
-
ฟังก์ชั่นสาธารณะรับ($key){
if(in_array($key,array('uid','username','usertype','url','expiry'))){
ส่งคืน $this->session[$key];
}อื่น{
if(isset($this->session['value'][$key])){
ส่งคืน $this->session['value'][$key];
-
กลับเป็นโมฆะ;
-
-
ฟังก์ชั่นสาธารณะ gc ($ ไฟล์, $ เวลา = 1200) {
$lasttime = file_get_contents($ไฟล์);
ถ้า($ครั้งสุดท้าย + $เวลา<$นี่->_เวลา){
file_put_contents($ไฟล์,$นี่->_เวลา);
ส่งคืน $this->_model->delete('activetime+expiry<'.$this->_time);
-
-
ฟังก์ชั่นสาธารณะทำลาย () {
$นี่->เซสชัน['uid'] = 0;
$นี่->เซสชัน['ชื่อผู้ใช้'] = '';
$นี่->เซสชัน['ประเภทผู้ใช้'] = -1;
$this->session['expiry'] = $this->_expiry;
$this->session['value'] = array();
$this->_setCookie($this->_sessionPrex.'_sid',$this->session['sid'],$this->_expiry);
$this->_setCookie($this->_sessionPrex.'_uid',$this->session['uid'],$this->_expiry);
-
ฟังก์ชั่นสาธารณะ __destruct(){
$นี่->_บันทึก();
-
ฟังก์ชั่นส่วนตัว _save(){
$dbSession = $this->เซสชัน;
$dbSession['value'] = ทำให้เป็นอนุกรม($dbSession['value']);
if(strlen($dbSession['value'])>255)$this->_error('session->value is too long!');
ถ้า($นี่->ใหม่ == 1){
//เพิ่มขึ้น
$this->_model->insert($dbSession);
}อื่น{
//ต่ออายุ
$sid = $dbSession['sid'];
$this->_model->update(array_slice($dbSession,1),'sid=''.$sid.''');
-
-
ฟังก์ชั่นส่วนตัว _getSession($sid){
$dbSession = $this->_model->detail('sid = ''.$sid.''');
if(!$dbSession)ส่งคืนเท็จ;
$dbSession['value'] = ยกเลิกการซีเรียลไลซ์($dbSession['value']);
$this->session = array_merge($dbSession,$this->session);
กลับเป็นจริง;
-
ฟังก์ชั่นส่วนตัว _getSid(){
$sid = strip_tags($_COOKIE[$this->_sessionPrex.'_sid']);
ถ้า(strlen($sid)==32){
ถ้า($นี่->_getSession($sid)){
กลับเป็นจริง;
-
}อื่น{
$sid = md5(เวลา().mt_rand(1,000,10000));
$this->_setCookie($this->_sessionPrex.'_sid',$sid);
-
$this->_setCookie($this->_sessionPrex.'_uid',0);
$นี่->เซสชั่น = อาเรย์(
'uid' => 0,
'ชื่อผู้ใช้' => '',
'ประเภทผู้ใช้' => -1,
'activetime' => $this->_time,
'ip' => $this->_getip(),
'url' => strip_tags($_SERVER['REQUEST_URI']),
'หมดอายุ' =>$นี่->_หมดอายุ,
'value' => อาร์เรย์()
-
$นี่->เป็นใหม่ = 1;
$this->session['sid'] = $sid;
-
ฟังก์ชั่นส่วนตัว _setCookie($name,$value,$expiry=0){
ถ้า(ว่าง($หมดอายุ))$หมดอายุ = $this->_expiry;
ถ้า(ว่าง($นี่->_โดเมน)){
setcookie($name,$value,$this->_time + $expiry,'/');
}อื่น{
setcookie($ชื่อ,$value,$this->_time + $expiry,'/',$this->_domain);
-
-
ฟังก์ชั่นส่วนตัว _getip(){
กลับ getip();
-
ฟังก์ชั่นส่วนตัว _setOptions($options){
foreach ($ตัวเลือกเป็น $key=>$value){
if(in_array($key,array('sessionPrex','time','model','expiry','domain'))){
$คีย์ = '_'.$คีย์;
$this->$key = $value;
-
-
-
ฟังก์ชั่นส่วนตัว _error($msg){
โยน Phpbean_Exception ใหม่ ($ msg);
-
-
-
(โปรดทราบว่าโค้ดนี้ไม่สามารถใช้โดยตรงได้ บทความนี้ให้แนวคิดเป็นหลัก)