在写注册登录的时候,经常有需要检测用户状态.今天就专门研究了一下。还可以吧~不过应该还是有一些小的漏洞,先分享给大家,慢慢改进
这个是基于ThinkPHP框架的,其他的可以自己根据需求改
1.先新建一个tags.php文件,放在配置目录Conf下。
1
2
3
4
5
6
7
8
9
|
<?php
/*
* 添加行为
*
*/
return
array
(
'action_begin'
=>
array
(
'OnlineCheck'
),
);
?>
|
2.定义具体的功能
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
|
<?php
/*
* 定义行为: 在线更新
*/
class
OnlineCheckBehavior
extends
Behavior {
//行为参数
protected
$options
=
array
(
'ONLINE_CHECK'
=> true,
// 默认进行在线
'ONLINE_CHECK_TIME'
=> 10,
// 默认5分钟未活动,说明已下线
);
public
function
run(&
$params
) {
if
(C(
'ONLINE_CHECK'
)) {
// 更新session
if
((session(
'?login_account'
)) && (time() - session(
'access_time'
) > 60)) {
session(
'access_time'
, time());
}
// 在线更新
$ip
=
ip2long
(get_client_ip());
$online
= M(
'Online'
);
// 先删除在线表中 超过5分钟未活动的记录
//$sql = ' delete from __TABLE__ where ';
$map
[
'lasttime'
] =
array
(
'lt'
, time() - C(
'ONLINE_CHECK_TIME'
) * 60);
$icount
=
$online
->where(
$map
)->
delete
();
if
(session(
'?login_account'
)) {
// 如果是登录用户
$map
=
array
();
$map
[
'uid'
] = session(
'login_uid'
);
$map
[
'lastip'
] =
$ip
;
$id
=
$online
->where(
$map
)->getField(
'id'
);
if
(
empty
(
$id
)) {
// 不存在在线记录,则清空session
session(null);
}
else
{
$map
=
array
();
$map
[
'id'
] =
array
(
'eq'
,
$id
);
$data
[
'lasttime'
] = time();
$data
[
'lastip'
] =
$ip
;
$online
->where(
$map
)->save(
$data
);
}
}
else
{
// 不是登录用户 游客
unset(
$map
);
$map
[
'lastip'
] =
array
(
'eq'
,
$ip
);
$id
=
$online
->where(
$map
)->getField(
'id'
);
//dump($id);
if
(
empty
(
$id
)) {
// 不存在在线记录, 则添加
$data
=
array
();
$data
[
'uid'
] = 0;
$data
[
'account'
] =
'Guest'
;
$data
[
'nickname'
] =
'游客'
;
$data
[
'lasttime'
] = time();
$data
[
'lastip'
] =
$ip
;
$online
->add(
$data
);
}
else
{
$map
=
array
();
$map
[
'id'
] =
array
(
'eq'
,
$id
);
$data
[
'lasttime'
] = time();
$data
[
'lastip'
] =
$ip
;
$online
->where(
$map
)->save(
$data
);
}
}
}
}
}
?>
|
3.在具体的登录方法上添加
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
|
// 登录检测
public
function
checkLogin() {
// $this->redirect($url);
$username
=
strtolower
(
$this
->_param(
'usr'
));
$pwd
=
$this
->_param(
'pwd'
);
$url
=
$this
->_param(
'url'
);
// 目标地址
$is_error
= false;
if
(
empty
(
$username
)
or
empty
(
$pwd
)) {
$this
->assign(
'error_msg'
,
'用户名和口令不能为空'
);
$is_error
= true;
}
if
(!
$is_error
) {
$model
= M(
'Usr'
);
$map
[
'account'
] =
$username
;
$map
[
'upwd'
] =
strtoupper
(md5(
$pwd
));
$icount
=
$model
->where(
$map
)->
count
();
if
(
$icount
== 1) {
$list
=
$model
->where(
$map
)->find();
// 检测用户是否在线
if
(
$this
->isOnline(
$list
[
'id'
])) {
// <editor-fold defaultstate="collapsed" desc="if开始">
if
(
$list
[
'status'
]) {
session(
'login_account'
,
$username
);
session(
'login_nickname'
,
$list
[
'nickname'
]);
session(
'last_time'
, toDate(
$list
[
'last_time'
]));
if
(
$list
[
'last_ip'
]) {
session(
'last_ip'
, long2ip(
$list
[
'last_ip'
]));
}
else
{
session(
'last_ip'
, get_client_ip());
}
session(
'login_count'
,
$list
[
'login_count'
]);
session(
'login_uid'
,
$list
[
'id'
]);
session(
'login_pwd'
,
$list
[
'upwd'
]);
session(
'access_time'
, time());
//用户最后点击页面时间 session超时使用
///
$map
[
'id'
] =
$list
[
'id'
];
$data
[
'last_time'
] = time();
$data
[
'last_ip'
] =
ip2long
(get_client_ip());
$model
->where(
$map
)->save(
$data
);
$model
->where(
$map
)->setInc(
'login_count'
, 1);
// 检测是否有同一IP的记录,有更新,否则 添加
$online
= M(
'Online'
);
$map
=
array
();
$map
[
'lastip'
] =
ip2long
(get_client_ip());
$online_id
=
$online
->where(
$map
)->getField(
'id'
);
if
(
empty
(
$online_id
)) {
// 插入在线用户表
$data
=
array
();
$data
[
'uid'
] =
$list
[
'id'
];
$data
[
'account'
] =
$list
[
'account'
];
$data
[
'nickname'
] =
$list
[
'nickname'
];
$data
[
'lasttime'
] = time();
$data
[
'lastip'
] =
ip2long
(get_client_ip());
$online
->add(
$data
);
}
else
{
// 更新在线用户表
$data
=
array
();
$data
[
'uid'
] =
$list
[
'id'
];
$data
[
'account'
] =
$list
[
'account'
];
$data
[
'nickname'
] =
$list
[
'nickname'
];
$data
[
'lasttime'
] = time();
//$data['lastip'] = ip2long(get_client_ip());
$online
->where(
$map
)->save(
$data
);
}
}
else
{
$is_error
= true;
$this
->assign(
'error_msg'
,
'此用户已被禁止登录!'
);
}
// </editor-fold> if 结束
}
else
{
$is_error
= true;
$this
->assign(
'error_msg'
,
'此用户名已在其他电脑登陆,请'
. C(
'ONLINE_CHECK_TIME'
) .
'分钟后再试!'
);
}
}
else
{
$is_error
= true;
$this
->assign(
'error_msg'
,
'错误的用户名或口令!'
);
}
}
if
(
$is_error
) {
$this
->display(
'login'
);
}
else
{
$this
->redirect(
'Index/index'
);
// if (empty($url)) {
// $this->redirect('Index/index');
// } else {
// $this->redirect($url);
// }
}
}
/**
* 检测用户是否在线
* @access private
* @param int $uid 用户ID
* @return Boolean true=不在线
*/
private
function
isOnline(
$uid
) {
$ip
=
ip2long
(get_client_ip());
$online
= M(
'Online'
);
$map
[
'uid'
] =
array
(
'eq'
,
$uid
);
$list
=
$online
->where(
$map
)->find();
if
(
empty
(
$list
)) {
// 不存在
return
true;
}
else
{
// 存在,检测IP是否一致,否则,检测是否超过5分钟
if
(
$list
[
'lastip'
] ==
$ip
) {
return
true;
}
else
{
if
(
$list
[
'lasttime'
] < time() - C(
'ONLINE_CHECK_TIME'
) * 60) {
return
true;
}
else
{
return
false;
}
}
}
}
|
以上就是具体的PHP在线状态检测,同一时间只有一个用户可以存在,不过还没有考虑到非正常掉线等,cookie,session意外的处理,但是先分享出来吧,以后改进了再说。
本文转自 3147972 51CTO博客,原文链接:http://blog.51cto.com/a3147972/1219081,如需转载请自行联系原作者