跟踪PHP中的下载进度

时间:2012-04-13 09:33:34

标签: php iis download progress

所有

我已经构建了一个表单,如果用户填写表单,我的代码可以确定该用户需要下载哪些(大)文件。我用下载按钮显示每个文件,我想在按钮旁边显示该文件的下载状态(正在下载,取消/中止或完成)。因为文件很大(200 MB +),我使用一个众所周知的函数来读取要在chuncks中下载的文件。 我的想法是记录数据库中每个(100千字节)块的读数,这样我就可以跟踪下载的进度。 我的代码如下:

    function readfile_chunked($filename, $retbytes = TRUE) 
    {
          // Read the personID from the cookie 
          $PersonID=$_COOKIE['PERSONID'];
          // Setup connection to database for logging download progress per file
          include "config.php";
          $SqlConnectionInfo= array    ( "UID"=>$SqlServerUser,"PWD"=>$SqlServerPass,"Database"=>$SqlServerDatabase);
          $SqlConnection= sqlsrv_connect($SqlServer,$SqlConnectionInfo);
          ChunckSize=100*1024; // 100 kbyte buffer
          $buffer = '';
          $cnt =0;
          $handle = fopen($filename, 'rb');
          if ($handle === false) 
          {
                return false;
          }
          $BytesProcessed=0;
          while (!feof($handle)) 
          {
                 $buffer = fread($handle, $ChunckSize);
                 $BytesSent = $BytesSent + $ChunckSize;
                 // update database
                 $Query= "UPDATE [SoftwareDownload].[dbo].[DownloadProgress] SET     LastTimeStamp = '" . time() . "' WHERE PersonID='$PersonID' AND FileName='$filename'";
                 $QueryResult = sqlsrv_query($SqlConnection, $Query);
                 echo $buffer;
                 ob_flush();
                 flush();
                 if ($retbytes) 
                 {
                        $cnt += strlen($buffer);
                 }
          }
          $status = fclose($handle);
          if ($retbytes && $status) 
          {
                 return $cnt; // return num. bytes delivered like readfile() does.
          }
          return $status;
    }

奇怪的是我的下载以恒定的速率顺利运行,但我的数据库在尖峰中更新:有时我会在一秒钟内看到几十个数据库更新(所以几十个100千字节的块),下一刻我看到没有数据库更新(所以没有100 k块由PHP提供)长达一分钟(这个超时取决于下载的可用带宽)。一分钟没有进展的事实使我的代码认为下载已中止。 与此同时,我看到IIS的内存使用量在增加,因此我认为IIS可以缓冲PHP提供的数据块。 我的网络服务器在FastCGI模式下运行Windows 2008 R2数据中心(64位),IIS 7.5和PHP 5.3.8。有什么我可以做的(在我的代码中,在我的PHP配置或IIS配置中)以防止IIS缓存PHP提供的数据,或者有任何方法可以在PHP中查看生成的数据是否实际传递给了下载客户端? 提前谢谢!

2 个答案:

答案 0 :(得分:1)

由于没有得到有用的答案,我通过严格使用Apache来下载文件创建了一个真正的狡猾的解决方法。整个表单,CSS等仍然通过IIS提供,只是下载链接是Apache的服务器(反向代理服务器位于其间,所以用户不必操纵端口号,代理负责这一点)。 Apache不会缓存PHP输出,因此我在数据库中获得的时间戳是可靠的。

答案 1 :(得分:0)

我曾经问了一次 similar question ,并在那里得到了很好的答案。

基本上,您使用APC缓存来缓存变量,然后使用来自客户端的Ajax调用在不同的页面中检索它。

另一种可能性是对数据库执行相同操作。将进度写入数据库并让客户端使用Ajax调用来测试(比如每秒)。

相关问题