博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PHP的Session机制解析 1
阅读量:4562 次
发布时间:2019-06-08

本文共 4224 字,大约阅读时间需要 14 分钟。

一、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
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
' . $val; } echo $val; echo "
";}

 

转载于:https://www.cnblogs.com/deverz/p/11028059.html

你可能感兴趣的文章
Learning Python 008 正则表达式-003 sub()方法
查看>>
Linux的虚拟机拷贝到另外的操作系统时,NAT方式的静态IP无效,一直是获取的DHCP动态地址...
查看>>
要检测两个C文件的代码的抄袭情况
查看>>
PHP-多域名单点登陆方案
查看>>
iOS开发之应用内支付IAP全部流程
查看>>
【web技术】html特效代码(一)
查看>>
SWFObject: 基于Javascript的Flash媒体版本检测与嵌入模块
查看>>
高可用集群搭建
查看>>
Lua学习笔记
查看>>
Redis监控工具,命令和调优
查看>>
zabbix-mysql迁移分离
查看>>
jQuery调用WCF 说明
查看>>
算法第5章作业
查看>>
7.9 练习
查看>>
基于ArcGIS JS API的在线专题地图实现
查看>>
learnByWork
查看>>
Unity3D热更新之LuaFramework篇[04]--自定义UI监听方法
查看>>
lua 函数
查看>>
Git的基本命令
查看>>
四平方和
查看>>