文档章节

从两种handler看PHP的session机制

TopPGF
 TopPGF
发布于 2016/04/16 12:03
字数 1070
阅读 2
收藏 0
点赞 1
评论 0

一、session_start()

session_start()是session机制的开始,它有一定概率开启垃圾回收,因为session是存放在文件中,PHP自身的垃圾回收是无效 的,SESSION的回收是要删文件的,这个概率是根据php.ini的配置决定的,但是有的系统是 session.gc_probability = 0,这也就是说概率是0,而是通过cron脚本来实现垃圾回收。

session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440//过期时间 默认24分钟
//概率是 session.gc_probability/session.gc_divisor 结果 1/1000, 
//不建议设置过小,因为session的垃圾回收,是需要检查每个文件是否过期的。
session.save_path = //好像不同的系统默认不一样,有一种设置是 "N;/path"
//这是随机分级存储,这个样的话,垃圾回收将不起作用,需要自己写脚本

session会判断当前是否有$_COOKIE[session_name()];session_name()返回保存session_id的 COOKIE键值,这个值可以从php.ini找到 session.name = PHPSESSID //默认值PHPSESSID

如果不存在会生成一个session_id,然后把生成的session_id作为COOKIE的值传递到客户端.相当于执行了下面COOKIE 操作,注意的是,这一步执行了setcookie()操作,COOKIE是在header头中发送的,这之前是不能有输出的,PHP有另外一个函数 session_regenerate_id() 如果使用这个函数,这之前也是不能有输出的。

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

如果存在,那么session_id = $_COOKIE[session_name]; 然后去session.save_path指定的文件夹里去找名字为'SESS_' . session_id()的文件。读取文件的内容反序列化,然后放到$_SESSION中。

二、为$_SESSION赋值

比如新添加一个值$_SESSION['test'] = 'blah'; 那么这个$_SESSION只会维护在内存中,当脚本执行结束的时候,用把$_SESSION的值写入到session_id指定的文件夹中,然后关闭相关资源。

这个阶段有可能执行更改session_id的操作,比如销毁一个旧的的session_id,生成一个全新的session_id.一半 用在自定义 session操作,角色的转换上,比如Drupal.Drupal的匿名用户有一个SESSION的,当它登录后需要换用新的session_id。

if (isset($_COOKIE[session_name()])) {
          setcookie(session_name(), '', time() - 42000, '/');//旧session cookie过期
        }
        session_regenerate_id();//这一步会生成新的session_id
       //session_id()返回的是新的值

三、 写入SESSION操作

在脚本结束的时候会执行SESSION写入操作,把$_SESSION中值写入到session_id命名的文件中,可能已经存在,可能需要创建新的文件。

四、销毁SESSION

SESSION发出去的COOKIE一般属于即时COOKIE,保存在内存中,当浏览器关闭后,才会过期,假如需要人为强制过期,比如 退出登录,而不是关闭浏览器,那么就需要在代码里销毁SESSION,方法有很多:

  • setcookie(session_name(), session_id(), time() - 8000000, ..);//退出登录前执行

  • usset($_SESSION);//这会删除所有的$_SESSION数据,刷新后,有COOKIE传过来,但是没有数据。

  • session_destroy();//这个作用更彻底,删除$_SESSION 删除session文件,和session_id

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

session.save_handler = user

   

用户自定义session处理机制,更加直观 session_set_save_handler('open', 'close', 'read', 'write', 'destroy', 'gc');

session_start(), 执行open($save_path, $session_name)打开session操作句柄。 $save_path 在session.save_handler = files的情况下它就是session.save_path,但是如果用户自定的话,这个两个参数都用不上,直接返回TRUE。执行read($id) 从中读取数据.//这个参数是自动传递的就是session_id(),可以通过这个值进行操作。

脚本执行结束,执行write($id, $sess_data) //两个参数,很简单

   

假如用户需要session_destroy(),先执行destroy,再执行第2步

一个实际例子:

//SESSION初始化的时候调用
   function open($save_path, $session_name)
   {
     global $sess_save_path;
     $sess_save_path = $save_path;
     return(true);
   }
   //关闭的时候调用
   function close()
   {
     return(true);
   }
   function read($id)
   {
     global $sess_save_path;
     $sess_file = "$sess_save_path/sess_$id";
     return (string) @file_get_contents($sess_file);
   }
   //脚本执行结束之前,执行写入操作
   function write($id, $sess_data)
   {
     echo "sdfsf";
     global $sess_save_path;
     $sess_file = "$sess_save_path/sess_$id";
     if ($fp = @fopen($sess_file, "w")) {
       $return = fwrite($fp, $sess_data);
       fclose($fp);
       return $return;
     } else {
       return(false);
     }
   }
   function destroy($id)
   {
     global $sess_save_path;
     $sess_file = "$sess_save_path/sess_$id";
     return(@unlink($sess_file));
   }
   function gc($maxlifetime)
   {
     global $sess_save_path;
     foreach (glob("$sess_save_path/sess_*") as $filename) {
       if (filemtime($filename) + $maxlifetime < time()) {
         @unlink($filename);
       }
     }
     return true;
   }


本文转载自:http://www.nowamagic.net/librarys/veda/detail/1382

共有 人打赏支持
TopPGF
粉丝 0
博文 5
码字总数 755
作品 0
深圳
怎样在多台Web服务器上共享Session

在多台web服务器上共享session的问题,我们可以举一些案例来说明。比如:现在有三台php服务器,且实现了负载均衡,如何让这三台web服务器共享session数据? session数据默认是以文件的形式保...

小欣妹妹
2017/10/31
0
0
php使用redis作为session存储

PHP使用redis作为session存储方式 phpredis安装 phpredis的首页:https://github.com/phpredis/phpredis#installation 解压代码 执行以下命令 phpize./configuremake && make install 更改p......

PatrickWQy
2016/06/10
74
0
PHP 中 SESSION 反序列化机制

原文出处:乘物游心 简介 在php.ini中存在三项配置项: PHP session.save_path="" --设置session的存储路径session.save_handler="" --设定用户自定义存储函数,如果想使用PHP内置会话存储机...

乘物游心
2016/10/26
0
0
彻底明白php的session机制

1.session.save_handler = files * 1. session_start() 1). session_start()是session机制的开始,它有一定概率开启垃圾回收,因为session是存放在文件中, PHP自身的垃圾回收是无效的,SES...

雍雍_yoyo
2013/08/22
0
5
SESSION运行原理(见过的比较好的SESSION介绍 转载)

1,设置sessio保存形式: [Session] session.save_handler = files 对应php函数:bool sessionsetsavehandler (callable , callable ,callable ,callable , callable , callable [,callable ......

drewin
2015/05/21
0
0
说说session里相关的事情(一)

session工作机制是:当程序需要为某个客户端的请求创建一个session的时候,服务器首先会检查这个客户端是否包含了一个session标志,我们称之为sessionid,如果客户端不包含sessionid,会重新...

熊猫88
2015/12/16
52
0
关于session和memcache的若干问题

实现Session的功能,基本上是通过 * 设置客户端的Cookie来保存SessionID, * 然后把用户的数据保存在服务器端,最后通 * Cookie中的Session Id来确定一个数据是否是用户的, 原始 session.sa...

rihgtzhao
2015/09/24
600
0
PHP 实现Session入库/存入redis

对于大访问量的站点使用默认的Session 并不合适,我们可以将其存入数据库、或者使用Redis KEY-VALUE数据存储方案 首先新建一个session表 Mysql 的memory引擎采用内存表,所有数据存储在内存,...

eatnothing
2015/11/10
0
8
MicroPHP 2.2.0 发布

ver 2.2.0: 增加了: 1.$this->cache为最新的phpfastcache2.1,缓存功能更加强大,而且编写自己的缓存类非常容易。 2.自定义缓存类说明: $system['cache_drivers'] = array(); 自定义缓存类文...

狂奔的蜗牛.
2013/11/13
1K
8
PHP Session原理分析

Session是以扩展的形式嵌入到PHP内核的,所以我们可以把Session当成扩展来看待。一般扩展被载入到PHP时会调用扩展的MINIT函数,Session也不例外,当Session被载入到PHP内核时,MINIT函数将会...

我不叫大脸猫
2012/09/13
0
7

没有更多内容

加载失败,请刷新页面

加载更多

下一页

mybaitis 通过Mapping 实现多表查询

1.实体类 1.1 用于做多表查询的类 public class CustomerCard { private Integer id;//主键 private String cardNumber; private Integer customerId;//用户id private String customerName;......

kuchawyz
8分钟前
0
0
Java语言学习(八):集合类框架

Java中提供了各种数据集合类,这些类主要用于保存复杂结构的数据。下面将介绍常用的几种集合类的用法。 ArrayList集合可以看做一个动态的数组,比普通数组更加灵活,更适合保存未知数量的数据...

海岸线的曙光
9分钟前
0
0
SpringBoot下Redis相关配置是如何被初始化的

参考网页 SpringBoot集成Redis的原理 https://blog.csdn.net/hry2015/article/details/74276423 https://blog.csdn.net/hry2015/article/details/75451705 application.yml配置文件中的属性是......

karma123
10分钟前
1
0
数据库事务的四大特性以及事务的隔离级别

本篇讲述数据库中事务的四大特性(ACID),并且将会详细地说明事务的隔离级别。 如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性: ⑴ 原子性(Atomicity) 原子性是...

Java大蜗牛
17分钟前
0
0
Spring Boot 整合 MyBatis/通用Mapper/PageHelper分页插件

整合MyBatis 整合通用Mapper 1. POM依赖配置 <properties><mapper.starter.version>2.0.3-beta1</mapper.starter.version></properties><!-- 通用Mapper --><dependency><groupId>t......

OSC_fly
26分钟前
0
0
CentOS7 双网卡绑定

环境 操作系统 CentOS7.5,禁用 NetworkManager 服务 网卡 eth0 网卡 eth1 绑定网卡 bond0 网卡 eth0 配置 修改 /etc/sysconfig/network-scripts/ifcfg-eth0 TYPE=EthernetBOOTPROTO=noneD......

Colben
27分钟前
0
0
zk实战--rpc框架集群化

在看此篇内容时需要浏览下面内容 netty实战--手写rpc框架 前文功能简介以及功能扩充 利用netty来实现一个点对点的rpc调用。客户端和服务端都是靠手写地址进行socket同学的,无法1对多,也无法...

xpbob
44分钟前
12
0
springboot 发送邮件

获取授权码 添加配置 # 账号和密码spring.mail.username=aaa@qq.comspring.mail.password=bbb# 服务器地址spring.mail.host=smtp.qq.comspring.mail.properties.mail.smtp.ssl.en...

阿豪boy
44分钟前
0
0
如何使用GNU Ring?

文章名:如何使用GNU Ring? 作者:冰焰火灵X 1079092922@qq.com 文章许可:CC BY-SA 4.0 ##1. 安装 下载GNU Ring 点击左边选择你的系统版本(这里以 GNU/Linux 为例,我使用的是Mint 18.3)...

ICE冰焰火灵X
47分钟前
4
0
深入理解springMVC

什么是spring MVC Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而...

Java填坑之路
53分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部