入门客AI创业平台(我带你入门,你带我飞行)
博文笔记

关于大文件下载引发的session锁问题。

创建时间:2018-01-11 投稿人: 浏览次数:171

最新写一个网盘项目,需要用到大文件上传和下载。在文件下载的位置遇到一个问题,导致用户操作被阻塞。简单介绍

主要知识点:

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();

声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
  • 上一篇:没有了
  • 下一篇:没有了
未上传头像