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意外的处理,但是先分享出来吧,以后改进了再说。呵呵
PHP实现用户在线状态检测的更多相关文章
- MySQL中实现DROP USER if EXISTS `test`,即创建新用户时检测用户是否存在
MySQL中实现DROP USER if EXISTS `test`,即创建新用户时检测用户是否存在 版权声明:本文为博主原创文章,欢迎大家转载,注明出处即可.有问题可留言,会尽快回复,欢迎探讨 ...
- HTML5在线状态检测和DOM Storage
除了离线资源缓存外,html5离线应用开发还可能用到以下技术 在线状态检测 navigator.onLine navigator.onLine 属性表示当前是否在线.如果为 true, 表示在线:如果 ...
- 机器学习算法在用户行为检测(UBA)领域的应用
[摘要]最近看到越来越多的安全圈的同学开始关注UBA或者UEBA的相关产品和技术,恰好这一段时也一直在跟进UBA产品的状况,正如Gartner报告所述,最具创新能力的UBA供应商往往都是一些初创公司, ...
- 大熊君学习html5系列之------Online && Offline(在线状态检测)
一,开篇分析 Hi,大家好,给大家拜个晚年!大熊君又和大家见面了,(*^__^*) 嘻嘻……,这系列文章主要是学习Html5相关的知识点,以学习API知识点为入口,由浅入深的引入实例,让大家一步一步的 ...
- 用户手势检测-GestureDetector使用详解
一.概述 当用户触摸屏幕的时候,会产生许多手势,例如down,up,scroll,filing等等. 一般情况下,我们知道View类有个View.OnTouchListener内部接口,通过重写他的o ...
- Java,用户刷屏检测\相似字符串检测
背景 近期有几个业务方提出一需求,期望判断一个用户在短期内是否存在刷屏现象,出现后能对其做出限制,并上报. 刷屏定义:取出用户近期20条评论,如果有50%的评论是"相似"的,则认为 ...
- Asp.NET MVC 使用 SignalR 实现推送功能二(Hubs 在线聊天室 获取保存用户信息)
简单介绍 关于SignalR的简单实用 请参考 Asp.NET MVC 使用 SignalR 实现推送功能一(Hubs 在线聊天室) 在上一篇中,我们只是介绍了简单的消息推送,今天我们来修改一下,实现 ...
- PHP注册与登录【3】 用户登录与退出
登录页面 login.html 负责收集用户填写的登录信息. <fieldset> <legend>用户登录</legend> <form name=&quo ...
- 读javascript高级程序设计17-在线检测,cookie,子cookie
一.在线状态检测 开发离线应用时,往往在离线状态时把数据存在本地,而在联机状态时再把数据发送到服务器.html5提供了检测在线状态的方法:navigator.onLine和online/offline ...
随机推荐
- Half Lambert
[Half Lambert] Half Lambert was a technique created by Valve as a way of getting the lighting to sho ...
- Lucene介绍及简单入门案例(集成ik分词器)
介绍 Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和 ...
- Python 爬虫之 Scrapy 分布式原理以及部署
Scrapy分布式原理 关于Scrapy工作流程 Scrapy单机架构 上图的架构其实就是一种单机架构,只在本机维护一个爬取队列,Scheduler进行调度,而要实现多态服务器共同爬取数据关键就是共享 ...
- Unity Remote 5 使用
从哪里下载,我是从应用商店里下载的 一. Android版 首先应该确保安装了最新的 Android SDK(这对于在设备上设置端口转发非常必要). 然后,使用 USB 连接线连接设备与电脑,并启动U ...
- Spring Data JPA动态查询(多条件and)
entity: @Entity @Table(name = "data_illustration") public class Test { @Id @GenericGenerat ...
- [原创]SOUI GDI+渲染引擎下的字体特效,抛砖引玉
由于SOUI是一种双渲染引擎的DUI库,默认在SKIA渲染引擎下是支持特效字体的,具体请参考DEMO中的源码. 但是使用GDI+渲染时是没有这些特效的,着实比较苦恼,此代抛砖引玉,细节实现 请自己再去 ...
- hdu 4068 I-number
#include<stdio.h> #include<string.h> ]; int al; int mysum() //求各位和 { ; al=strlen(a); ; i ...
- 1517 u Calculate e
1. 最前面的格式要记得输入. 2. 计算的时候要从3开始重新计算, 否则会丢失精度. 3. 更快的方式就是打表. #include <iostream> using namespace ...
- Qt之QML开发常用知识
小技巧: 1. QML的内部逻辑可以直接调试 2. ctrl+ alt + space,在写QML时,可以直接调出工具条 3. 属性以小写字母开发 4. 属性改变事件,基本都是on+Property+ ...
- javascript总结27 :特殊引用类型String/Number/Boolean
为了方便操作基本数据类型,JavaScript还提供了三个特殊的引用类型:String/Number/Boolean 1 Number 例如: var s1 = "zhangsan&quo ...