找回密码
 加入
搜索

使用 MySQL 开始 PHP 会话

[复制链接]
发表于 2005-11-28 22:22:13 | 显示全部楼层 |阅读模式
来自:http://www.coolcode.cn/?p=43 " A- u* e7 y& f" p% H( [
默认情况下,PHP会话(session)是通过文件来保存的。这样做有以下几个缺点:
; a+ I$ i8 Q+ }3 i& b  y$ `( P: f* W! C. b
会话文件一般都很小,但文件数却很多,在文件系统中保存许多这样的小文件非常浪费空间,且效率不高。
- J' b! \$ J! b" u4 E9 x, ?6 O# U2 E
* G+ l3 T0 D4 t分布式的站点难以利用会话文件来共享会话。 # h8 H9 V8 V9 a) w
会话文件方式不利于统计在线用户的会话信息。
; c4 h* Q8 a  c( l6 O( d% g. \/ R" J; |1 H- l
为解决以上问题,我们可以考虑用数据库来保存会话信息。 1 D5 G4 j6 b/ A, p9 L& W% k6 E
( z, O' w& j: S
对于 PHP 开发来说,保存会话用 MySQL 是一个非常不错的选择。MySQL 提供一种建立在内存中的表类型 Heap,如果每条会话数据量很小的话,可以考虑用这种类型的表来进一步优化性能。但是 Heap 类型的表有许多限制,例如它不支持 text 类型的字段,因此如果在无法预测会话数据记录长度的情况下,选择 MyISAM 是比较合适的,这种类型的表没有事物处理开销,对于基于磁盘的表可以得到最优性能。
! I: |; B0 t# _# B4 o9 M, C  g3 j, {- j8 P0 ~
下面是 sessions 表的结构:
9 A8 Y4 Y6 Q% W8 G
DROP TABLE IF EXISTS `sessions`;  
2 U. F$ R' t: m' M* S/ s: HCREATE TABLE `sessions` (  % l2 }9 q1 N' }. e
  `session_id` varchar(32) NOT NULL default '',  & W  Q) W) Z0 d1 H! _7 z! }$ V
  `user_id` int(10) unsigned NOT NULL default '0',  
" R2 p% h" v! k" h/ Q1 \3 G1 N4 d  `data_value` text NOT NULL,  $ w3 I+ |* Z2 B( q; U( j' M
  `last_visit` timestamp(14) NOT NULL,  
; |; V! X" `' L* E4 [  PRIMARY KEY (`session_id`),  
" b' M/ y% G" g8 x; T& m8 `  KEY `user_id` (`user_id`)  ) W2 ~+ x' h6 ?
) TYPE=MyISAM;
9 G( l" B7 ^- q' K7 y3 Z1 R% n+ s

3 j3 Y7 l( n$ ~6 GPHP 支持用户会话模块,可以通过 session_set_save_handler 来设置自定义的会话处理函数。因为默认的处理模块是 files,因此要在用 session_set_save_handler 设置会话处理函数之前,先用 session_module_name(’user’) 来告诉 PHP 使用用户会话模块, 而session_set_save_handler 必须要在 session_start 之前执行。 1 I1 X5 W3 D& [, u

1 j5 M, p* W/ T; n' j! v; `; s用户会话数据在会话处理函数中都是序列化之后的,要取出其中的某个会话变量,可以对其进行反序列化,默认是 php 序列化方式,可以用 unserialize 函数来反序列化。 ) J6 x( D0 r+ R- X/ W8 T- O/ k" [

/ S! ~( A$ ?) P, [* ~1 o/ Y  t下面的代码定义了一个用 MySQL 来处理 PHP 会话的类,其中所使用的 class_mysql.php 请参见 《超级简单但超级实用的 PHP 的 mysql 类》 。 6 Z1 t* L% }7 B1 f' R8 Q
<?php  
3 Z6 y. H( b. X# A% d: I6 C/**    E$ G7 h% q+ O1 \7 e
* @author Ma Bingyao  ) A6 |% p" F8 h+ e- ~% e
* @copyright (C) 2005 CoolCode.CN  . Y+ Y. ^) k( J, s; D* t( }
*/  % @& U# Z' i6 s* O2 i7 |3 H9 _
   / @; ]0 W+ e) o4 C5 I/ v
require_once("class_mysql.php");  
% f6 J6 \& u/ J' [3 o   , a/ \4 Z$ e4 O# Y
class session {  
; k( w  c7 P* U. P' `1 h9 ?    var $db;  7 U! K( b: Q2 |2 g8 h* o" d- D0 x, g
    function session(&$db) {  
  n' ~$ h# P% |8 ^) g        $this->db = &$db;  
% Y/ m  n$ k  @! [        session_module_name('user');  " s, i3 H$ e; V) N! v
        session_set_save_handler(  & r* f, H1 u0 ?
            array(&$this, 'open'),  
# \, @5 ~, j8 S! Q3 v, B            array(&$this, 'close'),  
: T$ Q) {5 w; T8 O* L6 i. h            array(&$this, 'read'),  
" D9 E9 S2 ~3 w: W+ A! D8 g) e8 ]* e            array(&$this, 'write'),  , S" z1 w/ b/ z7 T( ~( K# @1 y
            array(&$this, 'destroy'),  * v  r2 |: k% o8 ?
            array(&$this, 'gc')  1 o4 @. m) a* a, R8 X
        );  
; O. T7 K" z4 O* w3 b) B        session_start();  
9 f! X( ]" B/ }; u* J    }  
1 \* z2 n# E) f    function open($path, $name) {    D+ {7 U0 `4 j! o# M
        return true;  
& Q' G0 B& H7 f! p3 P; z! s8 f    }  
# V& ]8 }7 \* N, C) q2 u    function close() {  
4 A3 m( E. C5 k) J) n$ B0 @        return true;  
) g! s  `: w: O5 D$ H    }  + l  l5 R- K! p1 ]0 D
    function read($session_id) {  : B& g/ {  d2 Q) E# K
        $session_id = $this->db->escape_string($session_id);  , `5 C( Q( R, T3 }" R8 g
        if ($row = $this->db->query("select * from `sessions` where `session_id` = '$session_id' limit 1")) {  
$ e) o# B/ a. a; R9 {8 }            return $row->data_value;  + k$ ~; n8 |; Q8 }
        }  
) B0 _) S/ c6 t' H! I* k& o        else {  ; C, O8 `, F1 [4 h; }6 q
            $this->db->query("insert into `sessions` set `session_id` = '$session_id'");  
& s# Q  M, @5 [9 T9 J            return "";  
8 ?  a* H+ y: j# \/ l        }  1 [5 T8 P- C. y, r; r1 d+ v# v" P
    }  1 @' {8 y: y- s- U7 Y4 ?
    function write($session_id, $data_value) {  1 c( L4 ^" s8 B5 b& W
        $session_id = $this->db->escape_string($session_id);  ) G( J$ {; a' j; T
        $data_value = $this->db->escape_string($data_value);  ( a/ N. G* W! t+ ~+ w/ W9 E
        $data = unserialize($data_value);  
4 h) O, H: i; ?* j        $this->db->query("update `sessions` set "   
; l- g% k5 E, M! z# h4 S                                . "`user_id` = '{$data['user_id']}', "  
0 N2 |' ^! @$ S5 n; j                                . "`data_value` = '$data_value', "  + w) O. x% C9 F' E
                                . "`last_visit` = null "  
" \/ ?. o: j: R! u: X# z: }  a8 Z                                . "where `session_id` = '$session_id'");  
# `  p# T! ?2 F, X6 D  }; N        return true;  
4 d0 ~' O, f! G! {    }  7 y% M; j# r0 w( ~! D
    function destroy($session_id) {  
: L& G% y$ E  `) Z9 e        $session_id = $this->db->escape_string($session_id);  
: B, @2 m$ i) g5 o2 B# h8 _        $this->db->query("delete from `sessions` where `session_id` = '$session_id'");  : y' c% V5 h7 ~7 W3 ?! n8 F. G
        return true;  
3 G' o0 P2 w2 H    }  
/ J* F1 b+ p( ?: w& e( r. x8 w8 ]    function gc($lifetime) {  
+ ~. c6 G  ?; E+ o  x" Z        $this->db->query("delete from `sessions` where unix_timestamp(now()) - unix_timestamp(`last_visit`) > $lifetime");  9 N2 O  ]+ h, F
        return true;  
+ W2 `( N/ R* o% S    }  
4 L1 j* L* T$ I# G1 v& I- L  n& @    function replace($session_id, $data_value) {  ) `7 W) p& F) {& }
        $session_id = $this->db->escape_string($session_id);  4 m) \9 d2 D: j% i
        $data_value = $this->db->escape_string($data_value);  / F) i$ x* s7 m/ G# {$ u4 F
        $data = unserialize($data_value);  ) b+ k" `% }; a/ W
        $this->db->query("replace `sessions` set "   
: o& [- _. B7 ^                                . "`session_id` = '$session_id', "  + z' t; R- c, D, _& S
                                . "`user_id` = '{$data['user_id']}', "  ( C5 L9 F. l  k6 x+ K3 H
                                . "`data_value` = '$data_value', "  9 q( J1 E5 N9 X: ]2 R
                                . "`last_visit` = null");  
% S. y: K0 Y! {1 n' G    }  
5 R7 b, A8 e: q' }+ s9 I: k    // get sessions by user_id  + O# ?; S& E: o# W
    function get($user_id) {  , @' |: u$ B+ X% q1 r3 `2 h& E2 }
        $user_id = $this->db->escape_string($user_id);  
' ?# ?( |$ T+ Z+ m4 D/ S        return $this->db->query("select * from `sessions` where `user_id` = '$user_id'");  4 Q/ J3 I' f6 N7 x. x2 M6 Q1 V
    }  & W' w; _* B" ~6 D; _3 G
    // get sessions list  
' E# l" T9 d) t1 J' V    function list($page, $rows) {  " w2 i$ ?3 g# t
        if ($page == 0) {  ) I3 O( _( f: y( \2 k9 Z  R
            return $this->db->query("select * from `sessions` order by `user_id`");  & P& \% q. e  j+ P0 k! P8 [; S, \5 U5 O
        }  
( y9 Z$ ]% G7 [4 r. d" e+ o        else {  * o& t- V7 U8 e$ y. j7 q% z
            $start = ($page - 1) * $rows;  
" B0 z4 p% J8 x, z  F, S( M! |            return $this->db->query("select * from `sessions` order by `user_id` limit $start, $rows");  
' |! ^  Q7 n. {3 s        }  5 o" y) e" ^1 R9 w- M5 X& N4 i
    }  5 D7 A7 i; n" d) M" e
}  
% r  S3 W4 ]5 J' ?; {; I, h5 }  C- L8 B?>
# y! y# S0 m; D5 {* C! _$ [
这个类的使用很简单,在原来使用 session_start 的地方,替换成 $session = new session($db) 就可以了。$db 表示 sessions 表所在的数据库。
8 m; Q/ n: G# r: v/ o% c5 D# a  T( ^& a, |
另外可以用 get 方法来获取某个用户的所有会话信息,通过 list 方法来得到所有用户会话列表。这样就可以方便的管理用户会话了。

Archiver|手机版|小黑屋|乱弹琴|重庆网址之家|多来米发 |

GMT+8, 2026-10-14 12:55 AM

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表