您的位置:首页 > 其它

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

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

主要知识点:

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();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: