PHP实现用户在线状态检测

简介:

   在写注册登录的时候,经常有需要检测用户状态.今天就专门研究了一下。还可以吧~不过应该还是有一些小的漏洞,先分享给大家,慢慢改进

  这个是基于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,如需转载请自行联系原作者
目录
相关文章
|
3月前
|
网络协议 PHP
|
6月前
|
小程序 PHP
[微擎]多系统共用accesstoken修复wifi小程序文本敏感词汇检测+图片检测原生php(可用)
[微擎]多系统共用accesstoken修复wifi小程序文本敏感词汇检测+图片检测原生php(可用)
|
PHP
php实现数字格式化,数字每三位加逗号的功能函数169856420=&gt;169,856,420
php实现数字格式化,数字每三位加逗号的功能函数169856420=&gt;169,856,420
188 0
|
PHP
PHP实现Workerman实例 高性能PHP Socket即时通讯框架
PHP实现Workerman实例 高性能PHP Socket即时通讯框架
359 0
|
消息中间件 PHP Windows
PHP实现php-amqplib/php-amqplib实例RabbitMq
PHP实现php-amqplib/php-amqplib实例RabbitMq
123 0
|
XML 移动开发 JSON
PHP使用yansongda/pay实现支付宝和微信的支付
PHP使用yansongda/pay实现支付宝和微信的支付
849 0
|
NoSQL PHP Redis
PHP结合redis实现点赞功能
PHP结合redis实现点赞功能
107 0
|
消息中间件 缓存 JSON
PHP实现think-queue介绍
PHP实现think-queue介绍
329 0
|
PHP
php实现定时任务hellogerard/jobby
php实现定时任务hellogerard/jobby
114 0