通常用户登陆,如果没有特别的限定, 同一个用户可以同时登陆, 今天搞了一个东西限定一个用户不能同时登陆到一个系统上, 后登陆者会把前面登陆的踢出来.(有点像QQ,同个帐号不能在多个地方同时在线, 后面登陆成功后就把前面登陆的掉线)

SQL : 两张表,一张是用户信息,另一张用来保存session

--
-- 数据库: `single_user`
--
CREATE TABLE IF NOT EXISTS `session` (
`username` varchar(50) default '',
`time` varchar(14) default '',
`session_id` varchar(200) NOT NULL default '0',
`userid` int(11) default '0',
PRIMARY KEY (`session_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `users` (
`userid` int(11) NOT NULL auto_increment,
`username` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
PRIMARY KEY (`userid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;

数据表 session 以session_id 为主键, 这个主键是 userid + user name + user login time 的 md5值算出来的. 每次用户登陆的时候就会像session表里插入一条,同时以userid username为条件查询旧的session记录并且删除他,所以当页面判断当前用户是否有效时,是通过$_SESSION数组里面保存在session_id值和数据库里取出来的session_id进行比较, 旧的session_id 在此用户第2次登陆时已经被删除,因此找不到,从而被退出系统.

代码部分
1.config.php 一些简单的配置,包括数据库的连接

<?php
$live_site = 'testing';
$session_life = 600;
function getConnect()
{
$db_local = 'localhost';
$db_user = 'root';
$db_pwd = 'root';
$db_name = 'single_userlogin'; $db_link = mysqli_connect($db_local, $db_user, $db_pwd,$db_name); if ($db_link)
{
return $db_link;
}
return false;
}

2. index.php 登陆页面

<?php
require_once('config.php');
$db = getConnect();
if (isset($_POST['username']) && isset($_POST['password']))
{
//处理用户登陆后的数据验证
$query = 'SELECT * FROM `users` WHERE `username`="' . trim($_POST['username']) . '" AND `password`="' .md5( trim( $_POST['password'] ) ) . '"';
$result = mysqli_query($db,$query); $rs_num = mysqli_num_rows($result); if ($rs_num > 0 )
{
//该用户存在
$row = mysqli_fetch_assoc($result);
$userid = $row['userid'];
$username = $row['username'];
$logintime = time(); //创建session_id值
$session_id = md5( $userid . $username . $logintime ); //登陆成功后要插入一条记录到session表中
$sql = 'INSERT INTO session SET `time`="'.$logintime.'", `session_id`="'.$session_id.'", `userid`='.$userid.', `username`="'.$username.'"';
mysqli_query( $db, $sql);
echo $sql; echo "<br>";
//并且要把session表里旧的session_id删除掉
$query = 'DELETE FROM `session` WHERE `userid`=' . $userid . ' AND `username`="' . $username . '" AND `session_id`!="' . $session_id . '"';
$old_session = mysqli_query($db,$query);
echo $query; //开启session, 把新登陆的用户信息进入$_SESSION中
session_name( md5( $live_site ) );
session_id( $session_id );
session_start(); $_SESSION['session_id'] = $session_id;
$_SESSION['userid'] = $row['userid'];
$_SESSION['username'] = $row['username'];
$_SESSION['logintime'] = $logintime;
echo '<pre>';
var_dump($_SESSION);
session_write_close();
echo '<script type="text/javascript">window.location.href="index2.php"</script>';
} else {
echo '<script type="text/javascript">window.location.href="index.php?mosmsg=Username Error"</script>';
}
} else {
//用户登陆框
?>
<form method="post" name="user_login" id="user_login" action="index.php">
Username:<input type="text" name="username" id="username" value=""/>
<br />
password:<input type="password" name="password" id="password" value=""/>
<br />
<input type="submit" name="submit" id="submit" value="Submit"/>
</form>
<?php
}
?>

3. index2.php 用户成功登陆后需要处理原来上一次该用户的session信息, 如果上一次此用户的登陆信息还有效,需要将其删除

<?php
require_once('config.php');
$db = getConnect();
session_name( md5( $live_site ) );
session_start(); $userid = $_SESSION['userid'];
$username = $_SESSION['username'];
$logintime = $_SESSION['logintime'];
$session_id = $_SESSION['session_id']; //判断用户是否有登陆
if ($session_id != session_id()) {
echo "<script>document.location.href='index.php?mosmsg=Invalid Session'</script>\n";
exit();
}
if ($session_id == md5( $userid . $username . $logintime )) {
$past = time() - $session_life; //删除已经超时但是记录还存在的记录
$query = "DELETE FROM session"
. "\n WHERE time < '" . (int) $past . "'"
. "\n AND userid <> 0"
;
mysqli_query($db,$query);
$current_time = time();
// update session timestamp 更新登陆用户的时间戳
$query = 'UPDATE #__session'
. '\n SET time="' . $current_time . '"'
. '\n WHERE session_id = "' . $session_id . '"'; //以当前用户登陆后产生的$session_id 来查询 session表里的记录是否存在
//如果不存在那么就跳到登陆页面
$query = "SELECT COUNT( session_id )"
. "\n FROM session"
. "\n WHERE session_id = '" . $session_id . "'"
. "\n AND username = '". $username . "'"
. "\n AND userid = ". $userid;
$session_rs = mysqli_query($db,$query);
$session_row = mysqli_fetch_row($session_rs);
$session_num = $session_row[0];
if ($session_num > 0 )
{
echo 'WELCOME<br / ><a href="logout.php">Logout</a>';
} else {
echo "<script>document.location.href='index.php?mosmsg=Admin Session Expired'</script>\n";
}
} else {
// session id does not correspond to required session format
echo "<script>document.location.href='index.php?mosmsg=Invalid Session'</script>\n";
exit();
}
?>

4. logout.php 退出用户,并且删除 SESSION

<?php
require_once('config.php');
$db = getConnect();
session_name( md5( $live_site ) );
session_start(); $userid = $_SESSION['userid'];
$username = $_SESSION['username'];
$logintime = $_SESSION['logintime'];
$session_id = $_SESSION['session_id']; $sql = 'DELETE FROM session WHERE userid='.$userid.' AND username="'.$username.'" AND session_id = "'.$session_id.'"';
mysqli_query($db,$sql);
session_destroy();
echo "<script>document.location.href='index.php'</script>\n";
exit();
?>

转载:https://www.cnblogs.com/belie8/articles/2196529.html

php同一个用户同时只能登陆一个, 后登陆者踢掉前登陆者(排他登陆)的更多相关文章

  1. 同一个PC只能运行一个应用实例(考虑多个用户会话情况)

    原文:同一个PC只能运行一个应用实例(考虑多个用户会话情况) class Program { private static Mutex m; [STAThread] static void Main( ...

  2. (26)基于cookie的登陆认证(写入cookie、删除cookie、登陆后所有域下的网页都可访问、登陆成功跳转至用户开始访问的页面、使用装饰器完成所有页面的登陆认证)

    获取cookie request.COOKIES['key'] request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age ...

  3. J2EE用监听器实现同一用户只能有一个在线

    这里我们讨论的是已登陆或将要登陆的用户,游客不在讨论的范围之内.这一点大家应该很容易就能理解的吧.                那么我们应该怎样去实现同一用户只能有一个在线这样的一个小功能呢? 有人 ...

  4. 怎么取消 Windows Server 2012 r2 RDP 限制每个用户只能进行一个会话(转)

    在 Windows Server 2008 / 2008 R2 上,如果希望多个远程用户使用同一个账号同时访问服务器的 Remote Desktop(RDP),只需通过管理工具-远程桌面下的“远程桌面 ...

  5. 怎么取消 Windows Server 2012 RDP 限制每个用户只能进行一个会话

    在 Windows Server 2008 / 2008 R2 上,如果希望多个远程用户使用同一个账号同时访问服务器的 Remote Desktop(RDP),只需通过管理工具-远程桌面下的“远程桌面 ...

  6. jfinal+H5的websocket 实现同一账户在不同地点不同电脑只能登陆一个(互相踢下线)

    jfinal+H5的websocket 实现同一账户在不同地点不同电脑只能登陆一个(互相踢下线):https://blog.csdn.net/liuyifeng1920/article/details ...

  7. 解决微信授权回调页面域名只能设置一个的问题 [php]

    最终的解决方案是:https://github.com/liuyunzhuge/php_weixin_proxy,详细的介绍请往下阅读. 在做项目集成微信登录以及微信支付的时候,都需要进行用户授权.这 ...

  8. 通过SessionID和用户名来保证同一个用户不能同时登录(单点登录)

    可以通过SessionID和用户名来保证同一个用户不能同时登录的问题,下面程序模仿了QQ的登录,当登录后判断当前帐号是否已经登录,如果登录.则踢掉以前登录的用户. 1.通过Application全局变 ...

  9. [asp.net mvc 奇淫巧技] 06 - 也许你的项目同一个用户的请求都是同步的

    一.感慨 很久前看到一篇博客中有句话大致的意思是:“asp.net 程序性能低下的主要原因是开发人员技术参差不齐”,当时看到这句话不以为然,然而时间过的越久接触的.net 开发人员越多就越认同这句话: ...

随机推荐

  1. java对象在内存中的分配

    java对象在内存中的分配 http://blog.csdn.net/qq_30753945/article/details/54974899

  2. 如何在oracle中导入导出dmp数据库文件

    Oracle数据导入导出imp/exp就相当于oracle数据还原与备份.exp命令可以把数据从远程数据库服务器导出到本地的dmp文件,imp命令可以把dmp文件从本地导入到远处的数据库服务器中.利用 ...

  3. CentOS7.5搭建Hadoop分布式集群

    材料:3台虚拟主机,ip分别为: 192.168.1.201 192.168.1.202 192.168.1.203 1.配置主机名称 三个ip与主机名称分别对应关系如下: 192.168.1.201 ...

  4. BIO,NIO,AIO的理解

    BIO:同步阻塞式IO,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善. NIO: ...

  5. Jedis使用工具类

    Redis 使用工具类: package com.qlwb.business.common.redis; import org.apache.log4j.Logger; import redis.cl ...

  6. Linux下安装软件遇见的问题汇总

    1.安装monodevelop 安装环境Linux Mint17.1 在软件在中心直接安装monodevelop,安装完成后直接启动界面“一闪而过”,解决办法: 软件中心安装 mono-complet ...

  7. jquery jquery中是否加()的问题

    自己总结的,慢慢修改再: 1带上()代表立即执行 去掉()代表当有事件发生的时候,我再执行

  8. 谷歌插件 JSON-Handle

    JSON-Handle http://jsonhandle.sinaapp.com/ 点击下载 插件下载后,在浏览器输入:chrome://extensions/ 将下载后的文件拖入 chrome浏览 ...

  9. It does not do to dwell on dreams and forget to live.

    It does not do to dwell on dreams and forget to live.不要过于依赖梦想,却忘了生活.

  10. SpringMVC项目的快速搭建

    Spring MVC提供了一个DispatcherServlet来开发Web应用.在Servlet2.5及2以下的时候只要在web.xml下配置<servlet>元素即可. 在Servle ...