11_会话原理与实现流程
1、会话的基本知识
# 会话## 1.会话是什么?客户端与服务器之间的对话交流## 2.为什么需要会话?-http 协议是无状态的(六亲不认)-同一用户多次访问同一网站,对网站来说,每次都是全新的-网站不能识别用户身份,不能为用户提供个性化服务
-用户需要被关怀被尊重-相同的操作,不应该换个页面就重复进行,例如登录、注册-用户信息应该在多个页面间共享,例如购物车## 3.会话的基本步骤> 和人与人之间的交流几乎一样1.开启会话:初次见面,相互介绍,递个名片,请多关照
2.访问网站:再次见面,报上姓名,原来是你,欢迎光临
3.数据交换:对话交流,及时反馈,谈话内容,立刻存档
4.销毁对话:相谈甚欢,恋恋不舍,谈判破裂,关门送客## 4.会话存储位置1.客户端:`cookie`
2.服务端:`session`## 5.PHP对应的操作变量
1.`$_COOKIE`
2.`$_SESSION`
2、客户端会话
<?php
namespace _0822;//客户端会话存储(cookie)//1.设置(正常情况下,会把中文的值变为Unicode编码,如果想显示中文,就用setrawcookie)
//raw是原始的意思// setcookie('site','php中文网');
setrawcookie('site','php中文网');//2.查看($_COOKIE是一个超全局变量,无作用域,任何地方都能用)
echo $_COOKIE['site'] ?? '未定义site'. '<hr>';//3.设置多个(建议使用数组语法)
setcookie('user[name]','admin');
setcookie('user[email]','admin@qq.com');
setcookie('user[age]',40);if(isset($_COOKIE['user'])){foreach($_COOKIE['user'] as $key => $value){printf('[%s] => %s<br>',$key,$value);}
}else{echo '未定义user';
}//4.删除(setcookie的第三个参数是过期时间)
//给一个已过期的时间就可以了
setcookie('welcome','hello world',time()-3600);/*** 将过多信息存储在客户端,并不合适* 1.数量受限:30个* 2.空间受限:4k* 3.安全隐患:天生不可避免* * 所以,会话信息推荐存储在服务器端* 客户端只需要保存一个会话id,用于标识访问身份即可*/
3、服务端会话
<?phpnamespace _0822;//服务器端会话(session)//1.启动会话
session_start();/*** 启动会话做了二件事* 1.浏览器:创建会话ID:PHPSESSID,一串md5加密的字符串* 2.服务器:创建与浏览器会话ID对应的会话文件,一个会话文件对应一个用户*///1.设置
$_SESSION['email'] = 'admin@php.cn';
//sha1是40位字符串,md5是32位
$_SESSION['password'] = sha1(md5('123456') . 'phpcn123');//session
//email|s:12:"admin@php.cn";password|s:40:"8dc7df199a6642d631c11de069b2357e4b470cd0";
//!email指变量名,s指字符串,12指它值的长度(admin@php.cn的长度)
//把用户的session信息进行了序列化,序列化就是把这些变量,数组,或对象转换为字符串形式,这样的话就方便存储到数据库中,继而便于通过网络进行传输,或者各个语言间的数据交换//2.更新
$_SESSION['email'] = 'peter@php.cn';//3.删除
// unset($_SESSION['email']);
// unset($_SESSION['password']);//一个一个删除太low了,更优雅地删除(一次性删除全部的session信息)
session_unset();//更狠地删除(直接把服务器的会话文件都删除了)
session_destroy();
比如说登录时,就带上登录信息,跳转到handler.php这个页面进行登录处理到这个数据表中进行验证,看看有没有这个用户,如果注册,就把用户插入到表中,退出就直接销毁会话就可以了.
4、登录页面(login.php)
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>用户登录</title><link rel="stylesheet" type="text/css" href="css/style.css">
</head><body><h3>用户登录</h3><form action="handle.php?action=login" method="post"><div><label for="email">邮箱:</label><input type="email" name="email" id="email" placeholder="demo@email.com" required autofocus></div><div><label for="password">密码:</label><input type="password" name="password" id="password" placeholder="不少于6位" required></div><div><button>提交</button></div></form><a href="register.php">还没有帐号, 注册一个吧</a>
</body></html>
5、入口文件(index.php)
<?php
namespace _0822;
session_start();
//判断是否已经登录?
if(isset($_SESSION['user'])){$user = unserialize($_SESSION['user']);
}
// print_r($user);
?>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>首页/入口文件</title><link rel="stylesheet" href="css/index.css">
</head>
<body><nav><a href="index.php">我的博客</a><?php if(isset($user)) :?><span style="margin-left: 300px;"><?=$user['name']?></span><a id="logout">退出</a><?php else:?><a href="login.php">登录</a><?php endif?></nav><script>document.querySelector('#logout').addEventListener('click',function(event){if(confirm('是否退出')){//禁用默认行为,其实就是禁用原<a>标签的点击跳转行为,使用事件中的自定义方法去处理event.preventDefault();//跳转到退出事件处理器window.location.assign('handle.php?action=logout');}})</script>
</body>
</html>
6、 注册页面(register.php)
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="stylesheet" type="text/css" href="css/style.css"><title>注册用户</title>
</head><body><h3>用户注册</h3><form action="handle.php?action=register" method="post" onsubmit="return compare()"><div><label for="name">呢称:</label><input type="text" name="name" id="name" placeholder="不少于3个字符" required autofocus></div><div><label for="email">邮箱:</label><input type="email" name="email" id="email" placeholder="demo@email.com" required></div><div><label for="p1">密码:</label><input type="password" name="p1" id="p1" placeholder="不少于6位" required></div><div><label for="p2">重复:</label><input type="password" name="p2" id="p2" placeholder="必须与上面一致" required></div><div><button>提交</button><span id="tips" style="color: red"></span></div></form><a href="login.php">我有帐号,直接登录</a><script>// 验证二次密码是否相等?function compare() {if (document.forms[0].p1.value.trim() !== document.forms[0].p2.value.trim()) {document.querySelector('#tips').innerText = '二次密码不相等';return false;}}</script>
</body></html>
7、处理器文件(handle.php)
<?phpnamespace _0822;use PDO;//开启会话:必须写在第一行session_start();//sql//查询用户表中的数据use表
$db = new PDO('mysql:dbname=phpedu', 'root', 'root');
$stmt = $db->prepare('SELECT * FROM `user`');
if($stmt->execute()){$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
}else{print_r($stmt->errorInfo());
}//获取用户操作类型
$action = strtolower($_GET['action']);switch ($action) {//1.登录case 'login':if ($_SERVER['REQUEST_METHOD'] === 'POST') {//获取登录用户的数据:邮箱和密码$email = $_POST['email'];$password = sha1($_POST['password']);// echo $password;// die($email);$result = array_filter($users, function ($user) use ($email, $password) {return $user['email'] === $email && $user['password'] === $password;});if (count($result) === 1) {//登陆成功,写入session$_SESSION['user'] = serialize(array_pop($result));exit('<script>alert("验证通过"); location.href="index.php";</script>');}}//2.退出//no breakcase 'logout':if (isset($_SESSION['user'])) {session_destroy();exit('<script>alert("退出成功");location.href="index.php"</script>');}//注册case 'register'://1.获取新用户数据$name = $_POST['name'];$email = $_POST['email'];$password = sha1($_POST['p2']);$register_time = time();//2.sql$sql = <<<SQLINSERT `user`SET `name` = ?,`email` = ?,`password` = ?,`register_time` = ?; SQL;$stmt = $db->prepare($sql);$data = [$name, $email, $password, $register_time];if ($stmt->execute($data)) {if ($stmt->rowCount() > 0) {//注册成功之后,让用户自动登录$sql = 'SELECT * FROM `user` WHERE `id` = ' . $db->lastInsertId();$stmt = $db->prepare($sql);$stmt->execute();$newUser = $stmt->fetch(PDO::FETCH_ASSOC);$_SESSION['user'] = serialize($newUser);exit('<script>alert("注册成功");location.href="index.php"</script>');} else {exit('<script>alert("注册失败");location.href="register.php"</script>');}} else {print_r($stmt->errorInfo());}//no breakdefault:exit('参数非法或未定义操作');
}
相关文章:
11_会话原理与实现流程
1、会话的基本知识 # 会话## 1.会话是什么?客户端与服务器之间的对话交流## 2.为什么需要会话?-http 协议是无状态的(六亲不认)-同一用户多次访问同一网站,对网站来说,每次都是全新的-网站不能识别用户身份…...
Java测试——junit的使用(2)
排序 我们同一个类下的多个用例的执行顺序是不确定的,如果需要指定固定的顺序,则需要在类上加这个注解 TestMethodOrder(MethodOrderer.OrderAnnotation.class)然后在想要第一个执行的用例上加上 Order(1)第二个执行的用例上注解: Order(…...
数据库(六): MySQL的主从复制和读写分离
文章目录一、为什么要使用主从复制和读写分离二、主从复制的原理三、如何实现主从复制3.1 master配置3.2 slave配置3.3 测试主从复制四、读写分离五、缺点一、为什么要使用主从复制和读写分离 注意到主从复制和读写分离一般是一起使用的。目的很简单,就是提高数据库…...
编程思想-0x00架构
产生架构的原因? 1、代码均摊 将不同的代码进行分块,然后简历联系,低耦合、高内聚; 原则上:合理的App架构应该是合理分配每个类、结构体、方法、变量的存在都应该遵循单一职责的原则 2、便于测试 测试确保代码质量&…...
QCon演讲实录(上):多云环境下应用管理与交付实践
作者:阿里云大数据基础工程技术团队——郭耀星 大家上午好!我是来自阿里云大数据基础工程技术团队的郭耀星,花名雪尧。今天我很高兴能够来到QCon,与大家分享我的经验和心得。在当前的多云环境中,作为运维支撑团队&…...
async thunk 解决 API 调用的依赖问题
async thunk 解决 API 调用的依赖问题 一句话节省看下面一堆内容的时间就是: async thunk 中可以使用 async/await 锁住其他的 action 操作 一般 API 之间存在三种情况: A 和 B 之间没有依赖关系 这样的情况下,A 和 B 可以各调用各的&#x…...
java 黑马头条 day3 实名认证分布式事务问题 seata
1 完善实名认证功能 1.1 实名认证分布式事务问题 1.1.1 问题分析 在昨天的实名认证代码中,审核完毕后添加 id5的演示异常,重新使用postman进行测试, 会发现 出现异常后 本地方法因为有 Transactional注解 对ap_user ap_user_realname的操作会回滚 而…...
测试开发之Django实战示例 第七章 创建电商网站
第七章 创建电商网站在上一章里,创建了用户关注系统和行为流应用,还学习了使用Django的信号功能与使用Redis数据库存储图片浏览次数和排名。这一章将学习如何创建一个基础的电商网站。本章将学习创建商品品类目录,通过session实现购物车功能。…...
【C++之容器篇】造轮子:list的模拟实现与使用
目录前言一、关于list1. 简介2. 成员类型二、默认成员函数1. 构造函数1. list()2. list(size_t n,const T& val T())和list(InputIterator first,InputIterator last)2. 拷贝构造函数3. 析构函数4. 赋值运算符重载函数三、迭代器1. 普通对象的正向迭代器2. const对象的正向…...
自动驾驶:决策规划算法岗位面经分享
本专栏分享 计算机小伙伴秋招春招找工作的面试经验和面试的详情知识点 专栏首页: 主要分享计算机算法类在面试互联网公司时候一些真实的经验 人情况是985本硕,硕士研究方向是强化学习在移动机器人路径规划中的应用,一段自动驾驶中小厂实习经历,秋招找的大都是机器人和自动驾…...
2.7、进程调度的时机、切换与过程、方式
1、进程调度的时机 进程调度\color{red}进程调度进程调度(低级调度),就是按照某种算法从就绪队列中选择一个进程为其分配处理机 进程在操作系统内核程序临界区\color{red}操作系统内核程序临界区操作系统内核程序临界区中不能\color{red}不能…...
工程管理系统源码+项目说明+功能描述+前后端分离 + 二次开发
工程项目各模块及其功能点清单 一、系统管理 1、数据字典:实现对数据字典标签的增删改查操作 2、编码管理:实现对系统编码的增删改查操作 3、用户管理:管理和查看用户角色 4、菜单管理:实现对系统菜单的增删改查操…...
ESP32S3系列--SPI从机驱动详解(一)
一、目的 在之前的博文中《ESP32S3系列--SPI主机驱动详解(一)》、《ESP32S3系列--SPI主机驱动详解(二)》我们详细讲解了ESP32S3上的SPI外设如何工作在主机模式并通过代码的形式帮助大家理解。 本篇我们将介绍SPI外设工作在从机模式下的使用知识点。 二、介绍 参考资料 http…...
【实战篇】移动端H5网页在ios滑动不流畅和禁止缩放问题
问题描述:移动端H5网页在ios滑动不流畅和禁止缩放问题 最近开发小程序,有一个富文本展示页面使用的是<webview>H5网页嵌入的,当你用 overflow-y:scroll 属性的时候,内容超出容器溢出滚动的效果很迟顿,特别是在IOS系统中,而且页面还会缩放。 解决方案: 1…...
12 循环神经网络(基础篇) Basic RNN
文章目录问题引入关于权重权重共享RNN CellRNN原理RNN计算过程代码实现RNN Cell维度说明代码RNN维度说明NumLayers说明计算过程代码参考实例问题分析多分类问题代码RNN CellRNN改进Embedding网络结构Embedding说明Linear说明代码课程来源: 链接课程文本参考…...
【C语言必经之路——第11节】初阶指针(2)
五、指针的运算1、指针与整数相加减看一下下面的代码:#include<stdio.h> int my_strlen(char* str) {int count0;while(*str!\0){count;str;//指针加减整数}return count; } int main() {int lenmy_strlen("abcdef");printf("%d\n",len);…...
SpringBoot学习(1)第一个SpringBoot程序
之前的SpringMVc就不在记录了,好像时间不太够了,但是springmvc作为javaweb的升级学一学对于springboot还是有较大的帮助的。 首先我们需要引入依赖,但是请注意,其中的一个不算是依赖,写法有所不同 首先需要引入 <…...
什么是热迁移?90%的企业都理解错误
科技的发展,新冠的冲击,让市场竞争愈发激烈。尽管云计算服务为企业免除了基础硬件的建设和维护成本,当企业需要进行业务跨架调整、升级维护、环境测试等场景而进行云迁移,其过程中所带来的停机时间,就变得尤为头疼了。…...
Scratch少儿编程案例-丝滑版贪吃蛇
专栏分享 点击跳转=>Unity3D特效百例点击跳转=>案例项目实战源码点击跳转=>游戏脚本-辅助自动化点击跳转=>Android控件全解手册点击跳转=>Scratch编程案例👉关于作者...
Linux系统之网卡子接口配置方法
Linux系统之网卡子接口配置方法一、本地系统环境检查1.检查系统版本2.检查系统内核版本3.检查本地IP地址二、网卡子接口介绍1.网卡子接口简介2.网卡子接口的优点3.网卡子接口的缺点三 加载802.1q 模块1.查看系统802.1q 模块信息2.加载802.1q 模块3.检查802.1q 模块加载状态四、…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...
Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...
DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态
前言 在人工智能技术飞速发展的今天,深度学习与大模型技术已成为推动行业变革的核心驱动力,而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心,系统性地呈现了两部深度技术著作的精华:…...
