关于大文件下载引发的session锁问题。
2018-01-11 16:12
162 查看
最新写一个网盘项目,需要用到大文件上传和下载。在文件下载的位置遇到一个问题,导致用户操作被阻塞。简单介绍
主要知识点:
php的session缺省用文件存储,当请求一个需要操作session的php文件(session_start())时,这个文件是会被第一个操作session的进程锁定,导致其他请求阻塞。其他请求会挂起在session_start()直到session文件解锁。
解决办法:
锁定的session文件直到脚本执行结束或者session正常关闭才会解锁,为了防止大量的php请求(需要使用$_SESSION数据)被锁定,可以在写完session后马上关闭,释放session锁。
这个函数只是关闭了写session,读还是可以的。
如果你理解了这句话,后面的代码你就不可以不用看了。
主要介绍下载,用户在下载文件使用的分片读取,推送到浏览器代码如下:
//临时设置该脚本执行永不超时
set_time_limit(0);
$file_pathinfo = pathinfo($fpath);
$file_name = $file_pathinfo['basename'];
$handle = fopen($fpath,"rb");
if (FALSE === $handle) {
return Util_BSResult::formatErrorResult(2, null, "Failed to open the file");
}
$filesize = filesize($fpath);
header("Content-type:video/mpeg4");//更具不同的文件类型设置header输出类型
header("Accept-Ranges:bytes");
header("Accept-Length:".$filesize);
header("Content-Disposition: attachment; filename=".$file_name);
$contents = '';
while (!feof($handle)) {
$contents = fread($handle, 8192);
echo $contents;
//刷新输出缓冲,把被释放出来的数据发送到浏览器
@ob_flush();
flush();
}
fclose($handle);
使用这种方法可以避免文件过大导致的php内存溢出,导致服务器报错。这段代码在之前之前,会有
4000
一个读取session的操作,也就是$_SESSION['user_info'].
修改之后的代码:
代码执行前添加:
session_start();
session_write_close();
主要知识点:
php的session缺省用文件存储,当请求一个需要操作session的php文件(session_start())时,这个文件是会被第一个操作session的进程锁定,导致其他请求阻塞。其他请求会挂起在session_start()直到session文件解锁。
解决办法:
锁定的session文件直到脚本执行结束或者session正常关闭才会解锁,为了防止大量的php请求(需要使用$_SESSION数据)被锁定,可以在写完session后马上关闭,释放session锁。
session_write_close();
这个函数只是关闭了写session,读还是可以的。
如果你理解了这句话,后面的代码你就不可以不用看了。
主要介绍下载,用户在下载文件使用的分片读取,推送到浏览器代码如下:
//临时设置该脚本执行永不超时
set_time_limit(0);
$file_pathinfo = pathinfo($fpath);
$file_name = $file_pathinfo['basename'];
$handle = fopen($fpath,"rb");
if (FALSE === $handle) {
return Util_BSResult::formatErrorResult(2, null, "Failed to open the file");
}
$filesize = filesize($fpath);
header("Content-type:video/mpeg4");//更具不同的文件类型设置header输出类型
header("Accept-Ranges:bytes");
header("Accept-Length:".$filesize);
header("Content-Disposition: attachment; filename=".$file_name);
$contents = '';
while (!feof($handle)) {
$contents = fread($handle, 8192);
echo $contents;
//刷新输出缓冲,把被释放出来的数据发送到浏览器
@ob_flush();
flush();
}
fclose($handle);
使用这种方法可以避免文件过大导致的php内存溢出,导致服务器报错。这段代码在之前之前,会有
4000
一个读取session的操作,也就是$_SESSION['user_info'].
修改之后的代码:
代码执行前添加:
session_start();
session_write_close();
相关文章推荐
- 关于php session文件锁机制引发的问题和定位过程
- 关于在浏览器中输入含有中文的下载的文件的问题引发的问题
- 关于asp.net中点击linkbutton下载solution中的文件的问题
- 关于android上下载网络文件大小异常的问题
- 关于qq邮箱 "该文件已达到200次的下载限制,您已不能下载该文件" 的问题处理
- 关于delphi中url文件下载编码问题(处理里面含有空格,汉字,字符)
- 关于IE等浏览器在下载JAR文件时的,将后缀更改为zip等问题及解决方案
- 关于windows 7 Build 6933 32Bit版本BT下载文件的问题!
- 关于浏览器下载文件的文件名会出现乱码的问题
- 关于ajax的下载文件被浏览器阻止的问题
- 解决关于php中文文件下载问题
- 关于利用浏览器下载网络视频文件的问题总结
- 关于创建Excel表格问题(保存至指定文件/弹出直接打开还是下载,并可以选择保存路径的对话框)
- 关于多标签浏览器中session共享引发的问题
- 关于Struts2文件下载时,下载方法被重复执行的问题
- 关于文件下载的几个问题总结
- 关于文件下载出现乱码问题
- 关于jsp下载csv文件问题
- 关于多标签浏览器中session共享引发的问题
- 有关于Linux系统下无法上传或下载想要文件的问题