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

 
login.php代码如下:
<?php
session_start(); require 'db.php'; if(!empty($_POST['submit'])) {
$uname = !empty($_POST['uname']) ? trim($_POST['uname']) : '';
$upwd = !empty($_POST['upwd']) ? trim($_POST['upwd']) : ''; //这里只是演示,实际情况是在数据库里查询并判断
if($uname == 'test' && $upwd == 'test') {
//这里假设test用户id为1
$uid = 1;
$session_id = session_id(); //判断是否已有用户登陆过
$res = mysql_query("SELECT session_id FROM tb_login_state WHERE uid={$uid}");
$data = mysql_fetch_assoc($res);
if(!empty($data)) {
$sessionId = $data['session_id'];
$sessionFilePath = session_save_path() . DIRECTORY_SEPARATOR . 'sess_' . $sessionId; //删除上次用户登陆的session文件
if(file_exists($sessionFilePath) && is_writable($sessionFilePath)) {
@unlink($sessionFilePath);
}
//删除用户登陆信息
mysql_query("DELETE FROM tb_login_state WHERE uid={$uid}");
}
//添加新的用户登陆信息
mysql_query("INSERT INTO tb_login_state VALUES({$uid}, '{$session_id}')"); $_SESSION['userInfo'] = array(
'name' => $uname
);
echo '<script type="text/javascript">alert("您已成功登陆,跳转首页");</script>';
echo '<script type="text/javascript">location.href="index.php";</script>';
}
}
?>
<!DOCTYPE HTML>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>用户登陆页面</title>
</head>
<body>
<form action="" method="post">
用户名:<input type="text" name="uname" value="" />
密码:<input type="password" name="upwd" value="" />
<input type="submit" name="submit" value="登陆" />
</form>
</body>
</html>
index.php代码如下:
<?php
header('Content-Type:text/html;charset=utf-8');
session_start(); if(!empty($_SESSION['userInfo'])) {
echo '您好:', $_SESSION['userInfo']['name'];
} else {
header('Location:login.php');
}

db.php代码如下:

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

tb_login_state表结构如下:

CREATE TABLE `tb_login_state` (
`uid` int(11) unsigned NOT NULL COMMENT '用户ID',
`session_id` varchar(32) NOT NULL DEFAULT '' COMMENT '存储用户的session_id'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户登陆状态表';
如果是session存储方式不是文件,而是存在mysql,memcache,redis中,思路其实是一样的,都是把前一次的session_id保存。判断用户是否登陆过,如果登陆过就让上一次的session失效(删除session数据)。
 
(*通过设置session的过期时间和cookie的过期时间来让session失效是不严格的,最直接的方法是直接把session文件删除。)
 
推荐阅读:
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. OpenCV:初试牛刀-带滚动条的视频播放-2

    视频播放时点击窗口关闭按钮(即小叉号)关闭窗口 隐藏console控制台 使用VideoCapture和createTrackbar实现滚动条控制视频播放 #include<iostream&g ...

  2. 【Codeforces】CF 467 C George and Job(dp)

    题目 传送门:QWQ 分析 dp基础题. $ dp[i][j] $表示前i个数分成j组的最大和. 转移显然. 吐槽:做cf题全靠洛谷翻译苟活. 代码 #include <bits/stdc++. ...

  3. django从请求到响应的过程深入讲解

    django启动 我们在启动一个django项目的时候,无论你是在命令行执行还是在pycharm直接点击运行,其实都是执行'runserver'的操作,而ruserver是使用django自带的的we ...

  4. Spark 分布式SQL引擎

    SparkSQL作为分布式查询引擎:两种方式 SparkSQL作为分布式查询引擎:Thrift JDBC/ODBC服务 SparkSQL作为分布式查询引擎:Thrift JDBC/ODBC服务 Spa ...

  5. 线程池,queue模块增加用法

    1 同一个进程内的队列(多线程) import queue queue.Queue() 先进先出 queue.LifoQueue() 后进先出 queue.PriorityQueue() 优先级队列 ...

  6. Petapoco 查询 语法

    查询语句 Sql sql = Sql.Builder; sql.Select("spb_MailAddress.*") .From("spb_MailAddress&qu ...

  7. smfony设置量表之间的关系

    设置量表之间的关系 验证是否ok 查看我们定义是否有问题 数据库操作 http://www.2cto.com/database/201504/387197.html  设置时间段数据库自动插入时间 不 ...

  8. 装机 win7 64 IE11

    英文版win7,更改语言包 英文版 http://windows.microsoft.com/en-us/internet-explorer/download-ie 中文版 http://window ...

  9. 机器学习入门-数据下采样 np.random_choice

    1. np.random_choice(array, len)  进行随机的数据选择,array表示抽取的对象,len表示抽取样本的个数 数据的下采样是对多的数据进行np.random.choice ...

  10. 序列化和反序列化(json 和pickle)dumps 为序列化, json为反序列化

    json 可以在不同语言中进行使用 下面先介绍一下json的适用方法 import json, pickle t1 = { 'name':'alex', ', ' } t1 = json.dumps( ...