一、php的默认session机制

php默认用磁盘文件来实现session
在php.ini中session.save_handler = files定义session机制
session.save_path="D:\dev\xampp\tmp" 定义session的存储位置

1.1、启动session
session_start()。
sesson_start()函数是启动session的开始,session默认存放在文件中,且具有一定概率触发session的垃圾回收机制。
php自身的垃圾回收对session是无效的,因为默认session是存放在文件中的。
session的垃圾回收概率是根据
session.gc_probability =1
session.gc_divisor =1000
session.gc_maxlifetime =1440//过期时间 默认24分钟
这三个参数去计算的。
计算规则为:
触发概率 = session.gc_probability / session.gc_divisor; 结果 1/1000,

1.2、配置session.save_path
session.save_path在php.ini中提供了不同的配置方式:
session.save_path="D:\dev\xampp\tmp"
session.save_path="N;D:\dev\xampp\tmp"
其中N为正整数,表示目录分级存放:
若N=2,假设此时sessionId为 63f2k77g4r0ls06g3p93t0cpkd
那么,session信息的存放格式为:
D:\dev\xampp\tmp\6\3\sess_63f2k77g4r0ls06g3p93t0cpkd
使用分级存放时,session的垃圾回收机制将会无效,需要自己写脚本处理过期session文件。
且子目录php不会自己创建,需要手动去创建6/3/目录。
如果分2级存放,可以通过脚本去事先创建好:

function createSessionDir ()
{
$basePath = trim(explode(';', session_save_path())[1], '/\\');
$str = '0123456789abcdefghijklmnopqrstuvwxyz';
$len = strlen($str);
for ($i = 0; $i < $len; $i++) {
for ($j = 0; $j < $len; $j++) {
$path = $basePath . DIRECTORY_SEPARATOR . $str[$i] . DIRECTORY_SEPARATOR . $str[$j];
if (!@file_exists($path)) {
mkdir($basePath . DIRECTORY_SEPARATOR . $str[$i] . DIRECTORY_SEPARATOR . $str[$j]);
} }
}
}

1.3、sessionId
$_COOKIE[session_name()];中存放了当前session的sessionId信息。
其中session_name()取的是php.ini中的session.name = PHPSESSID 的值。

如果不存在会生成一个sessionId,然后将id作为cookie的值传递到客户端。
相当于执行setcookie()函数:

setcookie(session_name(),
session_id(),
session.cookie_lifetime,//默认0
session.cookie_path,//默认'/',当前程序跟目录下都有效
session.cookie_domain,//默认为空
)

按照php手册里的说明,使用setcookie()之前不能有任何输出,但是我测试时,在函数之前echo了内容是不会报错的。
原因是php5.3版本以下时,php.ini有一项配置output_buffering,此配置项,在php5.3以下是默认为0,在5.3以上则默认是4096。
因为使用的版本大于5.3,所以在测试的时候,默认是开启output_buffering的。
开启output_buffering的时候,无论是echo,还是var_dump,print_r,任何输出,都会在php脚本结束时,统一随着http响应返回给客户端,(超过4096大小时,可能会分段返回)。所以不会报错。

1.4、session赋值
添加一个session值:$_SESSION['name]='zhangsan',此时这个值会在内存中存在,当脚本执行完毕时,会将其写入到指定sessionId的文件中,然后关闭资源。
如网页的匿名用户存在一个session,当登录后需要更换session:

//删除旧的session信息
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), '', time() - 86400);
}
session_regenerate_id();//重新生成sessionId

1.5、销毁session信息
cookie中携带的session信息为即时cookie,保存在浏览器中,当浏览器关闭后,才会过期。
但是一般我们在用户退出登录时,就需要销毁其cookie和session信息,销毁的方式:

a、setcookie(session_name(), session_id(), time() - 86400);//退出登录前执行
b、unset($_SESSION);//会删除所有的$_SESSION数据,刷新后,有COOKIE传过来,但是没有数据
c、session_destroy();//彻底删除$_SESSION并删除session文件和sessionId

当不关闭浏览器的情况下,再次刷新,b和c都会有COOKIE传过来,但是找不到数据。

二、用户自定义处理机制
php.ini中配置session.save_handler = user 就会触发自定义处理机制其中user字符是随意的,不固定。
自 PHP 5.4 开始,可以使用下面的方式来注册自定义会话存储函数:
session_set_save_handler ( object $sessionhandler [, bool $register_shutdown = TRUE ] ) : bool
sessionhandler为实现了 SessionHandlerInterface接口的对象

MySession.php
<?php
/**
* Desc: 自定义session处理机制,>5.4
* Class: Session
* User: zb
* Date: 2019/6/14 18:32
*/ class MySession implements SessionHandlerInterface
{
private $savePath; public function close ()
{
return true;
} public function destroy ($sessionId)
{
$file = $this->savePath . '/sess_' . $sessionId;
if (file_exists($file)) {
@unlink($file);
}
return true;
} public function gc ($maxlifetime)
{
$sessionFiles = glob($this->savePath . '/sess_*');
foreach ($sessionFiles as $file) {
if (file_exists($file) && filemtime($file) + $maxlifetime < time()) {
@unlink($file);
}
}
return true;
} public function open ($savePath, $sessionName)
{
$this->savePath = $savePath;
if (!is_dir($this->savePath)) {
mkdir($this->savePath, 0777);
} return true;
} public function read ($sessionId)
{
return (string)@file_get_contents($this->savePath . '/sess_' . $sessionId);
} public function write ($sessionId, $sessionData)
{
return @file_put_contents($this->savePath . '/sess_' . $sessionId, $sessionData) === false ? false : true;
}
}

使用自定义session机制:

index.php
<?php
/**
* Desc: xxx
* User: zb
* Date: 2019/6/14 18:32
*/
include 'MySession.php';
$mySession = new MySession();
session_set_save_handler($mySession, true);
session_start();
if (!empty($_GET) && $_GET['user'] && $_GET['passwd']) {
$_SESSION['user'] = $_GET['user'];
$_SESSION['passwd'] = $_GET['passwd'];
printInfo($_SESSION, 'allSessionData');
printInfo($_COOKIE[session_name()], 'sessionId');
} else {
printInfo('get无数据');
} function printInfo ($val, $key = '')
{
header('Content-Type', 'text/html; charset=UTF-8');
$val = var_export($val, true);
if ($key) {
$val = $key . ' => ' . $val;
}
echo $val;
echo "<br>";
}

PHP的Session机制解析 1的更多相关文章

  1. PHP的Session机制解析 2

    在鸟哥的博客看到对php session的过期时间的一篇文章,在此记录. 原文地址:http://www.laruence.com/2012/01/10/2469.html 以下是鸟哥博客原文: 今天 ...

  2. Cookie/Session机制详解

    会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端 ...

  3. 理解Cookie和Session机制(转)

    目录[-] Cookie机制 什么是Cookie 记录用户访问次数 Cookie的不可跨域名性 Unicode编码:保存中文 BASE64编码:保存二进制图片 设置Cookie的所有属性 Cookie ...

  4. PHP中的SESSION机制

    [转] php中cookie和session是我们常用的两个变量了,一个是用户客户端的,一个用在服务器的但他们的区别与工作原理怎么样,下面我们一起来看看cookie和session机制原理吧.   c ...

  5. [转]Cookie/Session机制详解

    原文地址:http://blog.csdn.net/fangaoxin/article/details/6952954 会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用 ...

  6. 转:理解Cookie和Session机制

    原文: 理解Cookie和Session机制 摘要: Cookie工作原理 由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份.怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论 ...

  7. 关于cookie的文章(cookie与session机制)

    会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端 ...

  8. Session机制详解

    转自:http://justsee.iteye.com/blog/1570652 虽然session机制在web应用程序中被采用已经很长时间了,但是仍然有很多人不清楚session机制的本质,以至不能 ...

  9. 理解Cookie和Session机制

    转载: 理解Cookie和Session机制 会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录 ...

随机推荐

  1. SQL语言分类DDL、DML、DQL、TCL、DCL

    关系型数据库的SQL语句都可以分为4大类: 1. DDL(数据定义语言)     DDL 主要是指如下的四种SQL 语句,以 CREATE.DROP.ALRET开头和 TRUNCATE TABLE 语 ...

  2. 使用命令将ipa包上传到蒲公英

    参考:官文文档 请根据开发者自己的账号,将其中的 uKey 和 _api_key 的值替换为相应的值.   curl -F "file=@/Users/chenpeisong/Desktop ...

  3. linux主机hang住echo 0 > /proc/sys/kernel/hung_task_timeout_secs disables this message

    用dmesg显示如下图信息 问题原因: 默认情况下, Linux会最多使用40%的可用内存作为文件系统缓存.当超过这个阈值后,文件系统会把将缓存中的内存全部写入磁盘, 导致后续的IO请求都是同步的. ...

  4. 测开之路三十:Flask基础之jinja2模板继承

    实现某些位置的内容固定,某些位置的内容动态展示,如: 中文文档地址:http://docs.jinkan.org/docs/jinja2/templates.html#template-inherit ...

  5. python 访问 网页 获得源码

    >>> from urllib.request import urlopen >>> for line in urlopen('http://tycho.usno. ...

  6. 使用Excel表格的记录单功能轻松处理工作表中数据的方法

    使用Excel表格的记录单功能轻松处理工作表中数据的方法 记录单是将一条记录分别存储在同一行的几个单元格中,在同一列中分别存储所有记录的相似信息段.使用记录单功能可以轻松地对工作表中的数据进行查看.查 ...

  7. Django--Aadmin入门

  8. ustc FreeBSD / rust 镜像源

    http://mirrors.ustc.edu.cn/help/ Rust Crates 源使用帮助 地址 https://mirrors.ustc.edu.cn/crates.io-index/ 说 ...

  9. jmeter工作原理介绍,以及常见错误

    JMeter结果树响应数据中文乱码解决办法 打开jmeter配置文件搜索encoding修改编码格式改为utf-8 Jmeter服务器反馈登陆不成功问题 导入到JMeter后,执行场景,发现登录校验成 ...

  10. 转 cpu高 问题分析定位

    文章来源: http://www.blogjava.net/hankchen/archive/2012/08/09/377735.html 一个应用占用CPU很高,除了确实是计算密集型应用之外,通常原 ...