解决的思路是每当用户登陆时我们必需记录当前的用户id和session_id,如果有人在其它地方用此账号登陆时,我们把此用户id对应的session_id的session文件删除,并重新记录当前的session_id。那么之前的用户就失效了。

 
login.php代码如下:
  1. <?php
  2. session_start();
  3.  
  4. require 'db.php';
  5.  
  6. if(!empty($_POST['submit'])) {
  7. $uname = !empty($_POST['uname']) ? trim($_POST['uname']) : '';
  8. $upwd = !empty($_POST['upwd']) ? trim($_POST['upwd']) : '';
  9.  
  10. //这里只是演示,实际情况是在数据库里查询并判断
  11. if($uname == 'test' && $upwd == 'test') {
  12. //这里假设test用户id为1
  13. $uid = 1;
  14. $session_id = session_id();
  15.  
  16. //判断是否已有用户登陆过
  17. $res = mysql_query("SELECT session_id FROM tb_login_state WHERE uid={$uid}");
  18. $data = mysql_fetch_assoc($res);
  19. if(!empty($data)) {
  20. $sessionId = $data['session_id'];
  21. $sessionFilePath = session_save_path() . DIRECTORY_SEPARATOR . 'sess_' . $sessionId;
  22.  
  23. //删除上次用户登陆的session文件
  24. if(file_exists($sessionFilePath) && is_writable($sessionFilePath)) {
  25. @unlink($sessionFilePath);
  26. }
  27. //删除用户登陆信息
  28. mysql_query("DELETE FROM tb_login_state WHERE uid={$uid}");
  29. }
  30. //添加新的用户登陆信息
  31. mysql_query("INSERT INTO tb_login_state VALUES({$uid}, '{$session_id}')");
  32.  
  33. $_SESSION['userInfo'] = array(
  34. 'name' => $uname
  35. );
  36. echo '<script type="text/javascript">alert("您已成功登陆,跳转首页");</script>';
  37. echo '<script type="text/javascript">location.href="index.php";</script>';
  38. }
  39. }
  40. ?>
  41. <!DOCTYPE HTML>
  42. <html lang="zh-CN">
  43. <head>
  44. <meta charset="UTF-8">
  45. <title>用户登陆页面</title>
  46. </head>
  47. <body>
  48. <form action="" method="post">
  49. 用户名:<input type="text" name="uname" value="" />
  50. 密码:<input type="password" name="upwd" value="" />
  51. <input type="submit" name="submit" value="登陆" />
  52. </form>
  53. </body>
  54. </html>
index.php代码如下:
  1. <?php
  2. header('Content-Type:text/html;charset=utf-8');
  3. session_start();
  4.  
  5. if(!empty($_SESSION['userInfo'])) {
  6. echo '您好:', $_SESSION['userInfo']['name'];
  7. } else {
  8. header('Location:login.php');
  9. }

db.php代码如下:

  1. <?php
  2. $db = mysql_connect('127.0.0.1','root','') or die('connect error');
  3. mysql_select_db('test') or die('select db error');
  4. mysql_query('set names utf8') or die('set names error');

tb_login_state表结构如下:

  1. CREATE TABLE `tb_login_state` (
  2. `uid` int(11) unsigned NOT NULL COMMENT '用户ID',
  3. `session_id` varchar(32) NOT NULL DEFAULT '' COMMENT '存储用户的session_id'
  4. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户登陆状态表';
如果是session存储方式不是文件,而是存在mysql,memcache,redis中,思路其实是一样的,都是把前一次的session_id保存。判断用户是否登陆过,如果登陆过就让上一次的session失效(删除session数据)。
 
(*通过设置session的过期时间和cookie的过期时间来让session失效是不严格的,最直接的方法是直接把session文件删除。)
 
推荐阅读:
  1. http://www.laruence.com/2012/01/10/2469.html
 
 
 

php 账号不能同时登陆,当其它地方登陆时,当前账号失效的更多相关文章

  1. java 实现 一个账号只能在一个地方登陆,其他地方被下线

    其实方法有很多的,我这献丑了. 使用理解java 四大作用域. 思路:理解java 四大作用域的关键. 第一个地方登陆: 1.得到请求的SessionId 和 登陆的 用户名 2.把SessionId ...

  2. 修改 /etc/pam.d/login, linux 本地账号密码无法登陆,一直返回 登陆的login界面

    今天我在我虚拟机测试的时候遇到了一个问题.登陆centos一直是返回login,账号和密码没错,我也换了两个用户. 1.问题描述 我正常的输入用户名和密码 错误提示截图:返回登陆界面,我重新试了另外的 ...

  3. 通过游戏学python 3.6 第一季 第九章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁定账号--锁定次数--菜单功能'menufile

      通过游戏学python 3.6 第一季 第九章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁 ...

  4. 通过游戏学python 3.6 第一季 第八章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁定账号--锁定次数

    通过游戏学python 3.6 第一季 第八章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁定账 ...

  5. 通过游戏学python 3.6 第一季 第七章 实例项目 猜数字游戏--核心代码--猜测次数--随机函数和屏蔽错误代码--优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁定账号

    #猜数字--核心代码--猜测次数--随机函数和屏蔽错误代码---优化代码及注释--简单账号密码登陆--账号的注册查询和密码的找回修改--锁定账号 #猜数字--核心代码--猜测次数--随机函数和屏蔽错误 ...

  6. ASP.NET -- WebForm -- Cookie的使用 应用程序权限设计 权限设计文章汇总 asp.net后台管理系统-登陆模块-是否自动登陆 C# 读写文件摘要

    ASP.NET -- WebForm -- Cookie的使用 ASP.NET -- WebForm --  Cookie的使用 Cookie是存在浏览器内存或磁盘上. 1. Test3.aspx文件 ...

  7. 【Java EE 学习 70 上】【数据采集系统第二天】【数据加密处理】【登陆验证】【登陆拦截器】【新建调查】【查询调查】

    一.数据加密处理 这里使用MD5加密处理,使用java中自带加密工具类MessageDigest. 该类有一个方法digest,该方法输入参数是一个字符串返回值是一个长度为16的字节数组.最关键的是需 ...

  8. XE6 & IOS开发之开发者账号、苹果证书(1):关于开发者账号

    网上能找到的关于Delphi XE系列的移动开发的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 关于苹果开发者账号, 注 ...

  9. SSH安全登陆原理:密码登陆与公钥登陆

      SSH全称(Secure SHell)是一种以安全性闻名的应用层网络通信协议,用于计算机间的安全通信,是目前比较成熟的远程登陆解决方案. 它提供两种方法登陆: 1.密码登陆 2.公钥登陆   密码 ...

随机推荐

  1. g++多文件编译

    头文件:A.h void test(); 源文件:A.cpp #include <iostream> #include<thread> #include<chrono&g ...

  2. Java与C++语法的区别

    1. 注释可以在Java程序中起到文档标记的作用 类文档标记: 1)@version 2)@author 3)@param 4)@return 5)@exception 2. Java的字符占两个字节 ...

  3. Installation of Scylla on CentOS 7

    Scylla on CentOS 7 Use these steps to install Scylla using Yum repositories on CentOS. Prerequisites ...

  4. Mongodb下载、安装、配置与使用

    记得在管理员模式下运行CMD,否则服务将启动失败 一.下载 官网下载地址:https://www.mongodb.com/download-center?jmp=nav#community 为了方便下 ...

  5. push(),pop(),unshift(),shift()

    1.push() 往数组末尾添加一个或多个元素,返回新的长度 2.pop() 删除数组末尾元素,数组长度减1,返回被删除的值 3.unshift() 往数组开头添加一个或多个元素,返回新的长度 4.s ...

  6. python拓展2 collections模块与string模块

    知识内容 1.collections模块介绍 2.collections模块使用 3.string模块介绍及使用 一.collections模块介绍 collections模块中提供了很多python ...

  7. Ingress.yaml

    apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test-ingress namespace: default annotat ...

  8. python json.loads json.dumps(ensure_ascii = False) 汉字乱码问题解决

    python 转换为json时候 汉字编码问题 2017年03月23日 18:50:04 阅读数:5604 有这样一个需求: 需要一个json 文件 数据从数据库里查询出来 1. 设置文件头 # -* ...

  9. 3.circle (圆)

    1.HTML代码: <div class="circleOne"></div> <br/> <div class="circle ...

  10. J2SE 8的编译

    动态加载(修改)服务.高性动态业务逻辑实现(用脚本或模板引擎实现效率满足不了需求) package compile; import java.io.File; import java.io.IOExc ...