zoukankan      html  css  js  c++  java
  • PHP实现用户在线状态检测

    这个是基于ThinkPHP框架的,其他的可以自己根据需求改

     1.先新建一个tags.php文件,放在配置目录Conf下。

    <?php
     /*
     * 添加行为
     *
     */
     return array(
        'action_begin' => array('OnlineCheck'),
     );
     ?>

       2.定义具体的功能

    <?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.在具体的登录方法上添加

    // 登录检测
        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意外的处理,但是先分享出来吧,以后改进了再说。呵呵

  • 相关阅读:
    06 is和==的区别 encode()编码 decode()解码
    05 dic的增删改查 字典的嵌套 考试题dic.get()的相关使用
    03 编码 int ,bool,str的常用操作 主要讲str
    01 基本数据类型 变量 if语句
    04 列表的增删改查 常用方法 元祖 range
    02 while循环 格式化输出 运算符
    多校2 Harmonious Army hdu6598 网络流
    P3159 [CQOI2012]交换棋子 网络流
    P2172 [国家集训队]部落战争 最大流
    P2402 奶牛隐藏 网络流
  • 原文地址:https://www.cnblogs.com/ghjbk/p/8037478.html
Copyright © 2011-2022 走看看