一个开发环境有多个网站,需要使用不同的session,解决方案很多。不过这次也高大上一把,用数据库存,方便以后扩展。
PostgreSQL版
首先是数据库的部分
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
--drop table php_session create unlogged table php_session ( sess_id varchar (32) primary key , modify_time timestamp with time zone not null , sess_data varchar (3000) default '' ); create index concurrently idx_php_session_modify_time on php_session(modify_time); --set_session(id, data) create or replace function set_session( varchar , varchar ) returns void as $set_session$ with upsert as ( update php_session set modify_time = current_timestamp , sess_data = $2 where sess_id = $1 returning 1 ) insert into php_session (sess_id, modify_time, sess_data) select $1, current_timestamp , $2 where not exists ( select 1 from upsert ); $set_session$ language sql; --get_session(id) create or replace function get_session( varchar ) returns varchar as $get_session$ select sess_data from php_session where sess_id = $1 $get_session$ language sql; --del_session create or replace function del_session( varchar ) returns void as $del_session$ delete from php_session where sess_id = $1 $del_session$ language sql; --gc_session create or replace function gc_session() returns void as $del_session$ delete from php_session where modify_time < current_timestamp - interval '30 days' $del_session$ language sql; |
然后是PHP的部分
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
<?php session_set_save_handler( function ( $savePath , $sessionName ) { //open return true; }, function () { //close return true; }, function ( $id ) { //read $sql = "select get_session($1)" ; $stmt = pg_query_params(SESSION_CONN, $sql , array ( $id )); $result = pg_fetch_row( $stmt ); return $result [0]; }, function ( $id , $data ) { //write $sql = "select set_session($1, $2)" ; pg_query_params(SESSION_CONN, $sql , array ( $id , $data )); return true; }, function ( $id ) { //destroy $sql = "select del_session($1)" ; pg_query_params(SESSION_CONN, $sql , array ( $id , $data )); return true; }, function ( $maxlifetime ) { //gc //php needn't control the global session gc return true; } ); register_shutdown_function( 'session_write_close' ); ?> |
然后只要在session_start之前调用这个就可以了
至于SESSION_CONN,那是我定义的一个常量,表示一个指向session数据库的链接而已。
MySQL版
再总结一个针对MySQL的集成更多基础功能的例子:
表结构:
1
2
3
4
5
6
|
CREATE TABLE IF NOT EXISTS `sessioninfo` ( `sid` varchar (255) NOT NULL , `value` text NOT NULL , `expiration` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP , PRIMARY KEY (`sid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
session信息存储到数据库的类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
class MySessionHandler implements SessionHandlerInterface { /** * @access private * @var object 数据库连接 */ private $_dbLink ; /** * @access private * @var string 保存session的表名 */ Private $_sessionTable ; /** * @access private * @var string session名 */ private $_sessionName ; /** * @const 过期时间 */ const SESSION_EXPIRE = 10; public function __construct( $dbLink , $sessionTable ) { if (! is_object ( $dbLink )) { return false; } $this ->_dbLink = $dbLink ; $this ->_sessionTable = $sessionTable ; } /** * 打开 * @access public * @param string $session_save_path 保存session的路径 * @param string $session_name session名 * @return integer */ public function open( $session_save_path , $session_name ) { $this ->_sessionName = $session_name ; return 0; } /** * 关闭 * @access public * @return integer */ public function close() { return 0; } /** * 关闭session * @access public * @param string $session_id session ID * @return string */ public function read( $session_id ) { $query = "SELECT value FROM {$this->_sessionTable} WHERE sid = {$session_id} AND UNIX_TIMESTAMP(expiration) + " . self::SESSION_EXPIRE . " > UNIX_TIMESTAMP(NOW())" ; $result = $this ->_dbLink->query( $query ); if (!isset( $value ) || empty ( $value )) { $value = "" ; return $value ; } $this ->_dbLink->query( "UPDATE {$this->_sessionTable} SET expiration = CURRENT_TIMESTAMP() WHERE sid = {$session_id}" ); $value = $result ->fetch_array(); $result ->free(); return $value [ 'value' ]; } /** * 写入session * @access public * @param string $session_id session ID * @param string $session_data session data * @return integer */ public function write( $session_id , $session_data ) { $query = "SELECT value FROM {$this->_sessionTable} WHERE sid = '{$session_id}' AND UNIX_TIMESTAMP(expiration) + " . self::SESSION_EXPIRE . " > UNIX_TIMESTAMP(NOW())" ; $result = $this ->_dbLink->query( $query ); $result = $result ->fetch_array(); if (! empty ( $result )) { $result = $this ->_dbLink->query( "UPDATE {$this->_sessionTable} SET value = {$session_data} WHERE sid = {$session_id}" ); } else { $result = $this ->_dbLink->query( "INSERT INTO {$this->_sessionTable} (sid, value) VALUES ('{$session_id}', '{$session_data}')" ); } if ( $result ){ return 0; } else { return 1; } } /** * 销魂session * @access public * @param string $session_id session ID * @return integer */ public function destroy( $session_id ) { $result = $this ->_dbLink->query( "DELETE FROM {$this->_sessionTable} WHERE sid = '{$session_id}'" ); if ( $result ){ return 0; } else { return 1; } } /** * 垃圾回收 * @access public * @param string $maxlifetime session 最长生存时间 * @return integer */ public function gc( $maxlifetime ) { $result = $this ->_dbLink->query( "DELETE FROM {$this->_sessionTable} WHERE UNIX_TIMESTAMP(expiration) < UNIX_TIMESTAMP(NOW()) - " . self::SESSION_EXPIRE); if ( $result ){ return 0; } else { return 1; } } } |
1
2
3
4
5
6
7
8
9
|
$dbLink = new mysqli( "localhost" , "root" , "root" , "test" ); $sessionTable = "sessioninfo" ; $handler = new MySessionHandler( $dbLink , $sessionTable ); session_set_save_handler( $handler ); session_start(); $_SESSION [ 'name' ] = "test" ; echo $_SESSION [ "name" ]; //session_destroy(); |