标题:
用数据库管理PHP会话
[打印本页]
作者:
Nothing
时间:
2007-7-18 09:30
标题:
用数据库管理PHP会话
<
?
php
/*
// =======================================
用数据库来管理会话的最大动机:
通过部署多个Web服务器,可以平衡HTTP负载并利用数据库服务器,也可以解决服务器的性能瓶颈问题。
// =======================================
*/
/*
// 会话表结构
// 有一个附加的索引,它允许使用后面描述的自定义垃圾收集代码快速删除未使用的会话。
create talbe phpsession(
session_id varchar(50) not null,
session_variable text,
last_accessed decimal(15,3) not null,
primary key(session_id),
key last_acc (last_acessed)
)
*/
function
getMicroTime
(
)
{
// microtime()返回自格林威治时间
// 1970年1月1日0:00:00起计算的秒数
// 作为微秒部分和一个秒部分
// 例如: 0.08344800 100952237
// 将这两部分转换到一个数组中
$
mtime
=
explode
(
" "
,
microtime
(
)
)
;
// 返回这两部分之和
// 例如: 100952237.08344800
return
(
$
mtime
[
1
]
+
$
mtime
[
0
]
)
;
}
/*
// 每当初试化一个会话时由PHP调用会话打开处理器
// 总是返回true
*/
function
sessionOpen
(
$
database_name
,
$
table_name
)
{
// 数据库连接
// $connection
// 保存表名称的全局变量
// $session_table
// 将数据库名保存在一个全局变量中
global
$
connection
;
global
$
hostname
;
global
$
username
;
global
$
password
;
if
(
!
(
$
connection
=
@
mysql_connect
(
$
hostname
,
$
username
,
$
password
)
)
)
{
showerror
(
)
;
}
if
(
!
mysql_select_db
(
$
database_name
,
$
connection
)
)
{
showerror
(
)
;
}
// 将表名保存在一个全局变量中
global
$
session_table
;
$
session_table
=
$
table_name
;
return
true
;
}
/*
// 每当调用session_start()和读会话变量时
// 调用该函数
// 当会话不存在时返回""
// 当会话存在时返回(串行化的)字符串
*/
function
sessionRead
(
$
sess_id
)
{
// 访问DBMS连接
global
$
connection
;
// 访问保存表名称的全局变量
// 该表保存会话变量
global
$
session_table
;
// 组织一个查询以找到由$session_id识别的会话
$
search_query
=
"SELECT * FROM $sesson_table WHERE session_id= '$sess_id'"
;
// 执行查询
if
(
!
(
$
result
=
@
mysql_query
(
$
search_query
,
$
connection
)
)
)
{
showerror
(
)
;
}
if
(
mysql_num_rows
(
$
result
)
=
=
0
)
{
// 没有找到会话,返回一个空字符串
return
''
;
}
else
{
// 找到一个会话,返回串行字符串
$
row
=
mysql_fetch_array
(
$
result
)
;
return
$
row
[
"session_variable"
]
;
}
}
/*
// 当利用session_start()调用初试化一个会话时,
// 当注册或注销变量时和当修改会话变量时,
// 调用该函数。成功则返回true
*/
function
sessionWrite
(
$
sess_id
,
$
val
)
{
global
$
connection
;
global
$
session_table
;
$
time_stamp
=
getMicroTime
(
)
;
$
search_query
=
"SELECT session_id FROM $session_table
WHERE session_id = '$sess_id'"
;
// 执行查询
if
(
!
(
$
result
=
@
mysql_query
(
$
search_query
,
$
connection
)
)
)
{
showerror
(
)
;
}
if
(
mysql_num_rows
(
$
result
)
=
=
0
)
{
// 没有找到会话,则插入一个新的会话
$
insert_query
=
"INSERT INTO $session_table
(session_id, session_variable, last_accessed)
VALUES ('$sess_id', '$val', $time_stamp)"
;
if
(
!
(
$
result
=
@
mysql_query
(
$
insert_query
,
$
connection
)
)
)
{
showerror
(
)
;
}
}
else
{
// 找到存在的会话,更新会话变量
$
update_query
=
"
UPDATE $session_table
SET session_variable = '$val',
last_accessed = $time_stamp
WHERE session_id = '$sess_id'"
;
//
if
(
!
(
$
result
=
@
mysql_query
(
$
update_query
,
$
connection
)
)
)
{
showerror
(
)
;
}
}
return
true
;
}
/*
// 在关闭会话时执行函数
// 总是返回true
*/
function
sessionClose
(
)
{
return
true
;
}
/*
// 每当发出session_destroy()函数调用时
// 就会调用该函数。如果会话已经成功地删除则返回true
*/
function
sessionDestroy
(
$
sess_id
)
{
global
$
connection
;
global
$
session_table
;
$
delete_query
=
"
DELETE FROM $session_table
WHERE session_id = '$sess_id'"
;
if
(
!
(
$
result
=
@
mysql_query
(
$
update_query
,
$
connection
)
)
)
{
showerror
(
)
;
}
return
true
;
}
/*
// 垃圾收集处理器
// 利用session.gc_probability中指定的可能性
// 在会话开始时调用该函数
// 通过删除所有已经有最后$max_lifetime秒未使用的
// 会话来执行垃圾收集,其中$max_lifetime在
// session.gc_maxlifetime中设置
// 如果DELELTE查询成功则返回true
*/
function
sessionGC
(
$
max_lifetime
)
{
global
$
connection
;
global
$
session_table
;
$
time_stamp
=
getMicroTime
(
)
;
$
delete_query
=
"
DELETE FROM $session_table
WHERE last_accessed < ($time_stamp - $max_lifetime)"
;
if
(
!
(
$
result
=
@
mysql_query
(
$
delete_query
,
$
connection
)
)
)
{
showerror
(
)
;
}
return
true
;
}
?
>
利用PHP来注册用户定义的会话处理器
<?
php
// 调用来注册用户回调函数
session_set_save_handler
(
"sessionOpen"
,
"sessionClose"
,
"sessionRead"
,
"sessionWrite"
,
"sessionDestroy"
,
"sessionGC"
)
;
?
>
欢迎光临 编程开发论坛 (http://bbs.lihuasoft.net/)
Powered by Discuz! 6.0.0