关于大文件下载引发的session锁问题。
最新写一个网盘项目,需要用到大文件上传和下载。在文件下载的位置遇到一个问题,导致用户操作被阻塞。简单介绍
主要知识点:
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内存溢出,导致服务器报错。这段代码在之前之前,会有一个读取session的操作,也就是$_SESSION["user_info"].
修改之后的代码:
代码执行前添加:
session_start();
session_write_close();
- 上一篇:没有了
- 下一篇:没有了