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 相关文章推荐
在PWS上安装PHP4.0正式版
Oct 09 PHP
php面向对象全攻略 (十六) 对象的串行化
Sep 30 PHP
PHP把网页保存为word文件的三种方法
Apr 01 PHP
php获取URL中带#号等特殊符号参数的解决方法
Sep 02 PHP
php实现的支持imagemagick及gd库两种处理的缩略图生成类
Sep 23 PHP
完美实现wordpress禁止文章修订和自动保存的方法
Nov 03 PHP
PHP中file_exists()判断中文文件名无效的解决方法
Nov 12 PHP
通过php修改xml文档内容的方法
Jan 23 PHP
使用PHP生成图片的缩略图的方法
Aug 18 PHP
PHP常用文件操作函数和简单实例分析
Jun 03 PHP
Yii框架学习笔记之session与cookie简单操作示例
Apr 30 PHP
thinkphp5 路由分发原理
Mar 18 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
PHP采集相关教程之一 CURL函数库
2010/02/15 PHP
PHP执行zip与rar解压缩方法实现代码
2010/12/05 PHP
编写安全 PHP应用程序的七个习惯深入分析
2013/06/08 PHP
PHP 文件编程综合案例-文件上传的实现
2013/07/03 PHP
php中的PHP_EOL换行符详细解析
2013/10/26 PHP
php过滤XSS攻击的函数
2013/11/12 PHP
Linux下PHP安装mcrypt扩展模块笔记
2014/09/10 PHP
php去除头尾空格的2种方法
2015/03/16 PHP
php遍历、读取文件夹中图片并分页显示图片的方法
2016/11/15 PHP
Seajs的学习笔记
2014/03/04 Javascript
javascript中JSON对象与JSON字符串相互转换实例
2015/07/11 Javascript
js+css3制作时钟特效
2016/10/16 Javascript
vue2 自定义动态组件所遇到的问题
2017/06/08 Javascript
实现图片首尾平滑轮播(JS原生方法—节流)
2017/10/17 Javascript
jQuery EasyUI 选项卡面板tabs的使用实例讲解
2017/12/25 jQuery
微信小程序自定义组件封装及父子间组件传值的方法
2018/08/28 Javascript
在vue+element ui框架里实现lodash的debounce防抖
2019/11/13 Javascript
Ant-design-vue Table组件customRow属性的使用说明
2020/10/28 Javascript
[48:48]完美世界DOTA2联赛PWL S3 Magama vs GXR 第一场 12.19
2020/12/24 DOTA
跟老齐学Python之做一个小游戏
2014/09/28 Python
python实现手机通讯录搜索功能
2018/02/22 Python
Python利用lxml模块爬取豆瓣读书排行榜的方法与分析
2019/04/15 Python
零基础使用Python读写处理Excel表格的方法
2019/05/02 Python
Python3 批量扫描端口的例子
2019/07/25 Python
python 伯努利分布详解
2020/02/25 Python
Python对象的属性访问过程详解
2020/03/05 Python
伊利莎白雅顿官网:Elizabeth Arden
2016/10/10 全球购物
eharmony澳大利亚:网上约会服务
2020/02/29 全球购物
美国椅子和沙发制造商:La-Z-Boy
2020/10/25 全球购物
JSF面试题:Jsf中的核心类用那些?有什么作用?LiftCycle六大生命周期是什么?
2014/07/17 面试题
生产现场工艺工程师岗位职责
2013/11/28 职场文书
21岁生日感言
2014/02/27 职场文书
对教师的评语
2014/04/28 职场文书
俞敏洪北大演讲稿
2014/05/22 职场文书
2016年大学自主招生自荐信范文
2015/03/24 职场文书
MySQL聚簇索引和非聚簇索引的区别详情
2022/06/14 MySQL