PHP实现提高SESSION响应速度的几种方法详解


Posted in PHP onAugust 09, 2019

本文实例讲述了PHP实现提高SESSION响应速度的几种方法。分享给大家供大家参考,具体如下:

设置多级目录存储SESSION

默认session的存储目录是1级目录,如果用户量比较大,session文件数量就比较大,我们可以设置目录数为2,使用2级目录可以提交查找和存取速度。不过这种方式对速度的提升一般不是很明显,可以通过修改php.ini,进而修改session存储目录数。

session.save_path = "2;/tmp"

将SESSION存储到redis中

php中的session默认是存储在文件中的,支持redis存储方式,因为redis的键值数据时存储在内存中的,可以提高session的存取速度。

session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"

及时释放SESSION文件锁

我们在使用session时,需要先执行session_start()函数。

session_start()函数的作用如下:

判断http请求是否包含名为PHPSESSID的cookie,如果没有则创建该cookie并写入到http响应的头文件。

通过PHPSESSID查找对应的session文件,以读写方式打开的文件,然后读取里面的数据到内存。

然后我们一般会通过$_SESSION这个超全局变量,读取或者设置session的值,我们操作的时候,session的值都是保存在内存中的,默认在页面执行完毕之后,才会写入到对应的文件中。

我们通过下面的一段代码测试这个过程:

session执行过程分析

include "session_function.php"; 
//session_function.php代码在附录
session_start();
$_SESSION['name']="koastal";
echo "<br/>html content<br/>";
var_dump($_SESSION);
echo "<br/>";

输出结果

open
read
html content
array (size=1)
  'name' => string 'koastal' (length=7)
shutdown
write
close

通过上面的例子可以发现,在页面执行的过程中(页面的执行过程是指将php文件解析为对应的html文件的耗时,而不是用户在该页面上的停留时间),session文件是被锁定的。

对于一些耗时的操作,比如文件上传,发送邮件等,如果用户在页面upload.php文件中上传文件,然后他又打开了个人信息页面index.php,然而upload.php文件还没有执行完成,index.php中的session_start()就不能打开对于的session文件,一直等待到upload.php执行完毕。

session死锁示例程序

upload.php

<?php
session_start();
$_SESSION['name']='koastal';
sleep(10); //sleep 10s 模拟文件上传耗时

index.php

<?php
session_start();
var_dump($_SESSION);

通过上面的分析可以知道,session在页面执行完毕之后,才会写入到文件中,并释放文件锁。session的功能,我们一般都是在页面中的一部分用到的,当我们处理完session之后,可以使用session_commit()或者session_write_close()函数,提前将session的值写入到文件中,并释放文件锁。

session_commit过程分析

include "session_function.php"; 
//session_function.php代码在附录
session_start();
$_SESSION['name']="koastal";
session_commit();
echo "<br/>html content<br/>";
var_dump($_SESSION);
echo "<br/>";

输出结果

open
read
write
close

html content
array (size=1)
  'name' => string 'koastal' (length=7)

shutdown

我们可以看到,在执行了session_commit()之后,就提前将session内容写到文件中,并且关闭文件(释放文件锁)了。

死锁示例优化后程序

upload.php

<?php
session_start();
$_SESSION['name']='koastal';
session_commit();
sleep(10); //sleep 10s 模拟文件上传耗时

我们操作完session之后,先讲session数据写入到文件,然后再执行上传过程,就不会影响到其他页面使用该session文件了。

执行完session_commit之后

<?php
session_start();
$_SESSION['name'] = "koastal";
session_commit();
echo $_SESSION['name'];

session_commit的另一个名字是session_write_close,也就是将session信息写入并关闭文件的意思。session_commit之后,虽然session文件已经关闭,但是页面还在执行,只要没有执行session_unset内存中就还保存着session的值,所以我们还可以获取和输出session的值。其实,这个时候我们还可以给session赋值,但是这个赋值只是赋值到内存中,因为文件已经关闭,所以其他页面时访问不到session_commit();之后设置的session的值。

销毁session

既然已经探讨了这么多session的问题了,那么我们在说一下用户注销时,销毁session的操作。

通过上面的分析,我们知道session的值会保存在内存和文件两个地方。
session_start()会将对应文件打开,并将session数据读入到内存。
session_commit()会将内存中的session数据写入到文件中,并关闭文件。
不显示调用session_commit()的话,会在页面执行完毕之后,自动调用。

所以,我们需要删除内存中的session信息,并且删除session文件。

session_unset();  //删除内存中的session信息
session_destory(); //删除session文件

如果我们只是用session_unset();也能达到注销用户的效果,但是这样处理时间上是把session的数据设置为空,并且写入session文件中了,本质上并没有删除session文件。

上面的两部操作,销毁了服务器上的session值,此外,我们还需要清理保存在客户端中的cookie,完成真正意义上的注销操作。

注销登录完整代码

logout.php

<?php
session_unset();  //删除内存中的session信息
session_destory(); //删除session文件
setcookie('PHPSESSID', null, time()-10);//将cookie值设置为过期

附录

session_function.php

<?php
function open($save_path, $session_name) {
  echo __FUNCTION__,"<br/>";
  return (true);
}
function close(){
  echo __FUNCTION__,"<br/>";
  return (true);
}
function read($id){
  echo __FUNCTION__,"<br/>";
}
function write($id, $sess_data){
  echo __FUNCTION__,"<br/>";
  return (true);
}
function destroy($id){
  echo __FUNCTION__,"<br />";
  return(true);
}
function gc($maxlifetime){
  echo __FUNCTION__,"<br />";
  return true;
}
session_set_save_handler("open", "close", "read", "write", "destroy", "gc");
register_shutdown_function('shutdown');
function shutdown()
{
  echo __FUNCTION__,"<br />";
}

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP 无限分类三种方式 非函数的递归调用!
Aug 26 PHP
php中使用Imagick实现图像直方图的实现代码
Aug 30 PHP
php中json_encode中文编码问题分析
Sep 13 PHP
PHP将XML转数组过程详解
Nov 13 PHP
php sybase_fetch_array使用方法
Apr 15 PHP
dvwa+xampp搭建显示乱码的问题及解决方案
Aug 23 PHP
php 截取utf-8格式的字符串实例代码
Oct 30 PHP
ThinkPHP实现生成和校验验证码功能
Apr 28 PHP
解析 thinkphp 框架中的部分方法
May 07 PHP
php打开本地exe程序,js打开本地exe应用程序,并传递相关参数方法
Feb 06 PHP
php 中phar包的使用教程详解
Oct 26 PHP
php装饰者模式简单应用案例分析
Oct 23 PHP
php tpl模板引擎定义与使用示例
Aug 09 #PHP
php函数式编程简单示例
Aug 08 #PHP
因str_replace导致的注入问题总结
Aug 08 #PHP
PHP goto语句用法实例
Aug 06 #PHP
Laravel 6 将新增为指定队列任务设置中间件的功能
Aug 06 #PHP
Yii框架核心组件类实例详解
Aug 06 #PHP
PHP使用Session实现上传进度功能详解
Aug 06 #PHP
You might like
转生史莱姆:萌王第一次撸串开心到飞起,哥布塔撸串却神似界王神
2018/11/30 日漫
总结PHP如何获取当前主机、域名、网址、路径、端口和参数等
2016/09/09 PHP
mac系统下安装多个php并自由切换的方法详解
2017/04/21 PHP
Linux下 php7安装redis的方法
2018/11/01 PHP
Alliance vs AM BO3 第二场2.13
2021/03/10 DOTA
jquery中获得$.ajax()事件返回的值并添加事件的方法
2010/04/15 Javascript
jQuery UI 应用不同Theme的办法
2010/09/12 Javascript
拉动滚动条加载数据的jquery代码
2012/05/03 Javascript
浅谈javascript对象模型和function对象
2014/12/26 Javascript
JavaScript  event对象整理及详细介绍
2016/10/10 Javascript
Node.js批量给图片加水印的方法
2016/11/15 Javascript
js实现日历的简单算法
2017/01/24 Javascript
jQuery按需加载轮播图(web前端性能优化)
2017/02/17 Javascript
vue利用better-scroll实现轮播图与页面滚动详解
2017/10/20 Javascript
通俗易懂地解释JS中的闭包
2017/10/23 Javascript
深入理解Vue.js轻量高效的前端组件化方案
2018/12/10 Javascript
ajax跨域访问遇到的问题及解决方案
2019/05/23 Javascript
vue项目查看vue版本及cli版本的实现方式
2020/10/24 Javascript
[05:20]卡尔工作室_DOTA2新手教学_DOTA2超强新手功能
2013/04/22 DOTA
[54:28]EG vs OG 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/18 DOTA
最大K个数问题的Python版解法总结
2016/06/16 Python
python写一个md5解密器示例
2018/02/23 Python
Python爬虫基础之XPath语法与lxml库的用法详解
2018/09/13 Python
python文件和文件夹复制函数
2020/02/07 Python
澳大利亚领先的孕妇服装品牌:Mamaway
2018/08/14 全球购物
请编程遍历页面上所有 TextBox 控件并给它赋值为 string.Empty
2015/12/03 面试题
物业经理求职自我评价
2013/09/22 职场文书
老师推荐信
2013/10/28 职场文书
博士研究生自我鉴定范文
2013/12/04 职场文书
校长寄语大全
2014/04/09 职场文书
单位委托书怎么写
2014/09/21 职场文书
2014年社区党建工作汇报材料
2014/11/02 职场文书
小学生红领巾广播稿
2015/08/19 职场文书
2016年劳模先进事迹材料
2016/02/25 职场文书
JavaScript 定时器详情
2021/11/11 Javascript
最新动漫情报:2022年7月新番定档超过30部, OVERLORD骨王第四季也在其中噢
2022/05/04 日漫