跟踪的下载进度在PHP
所有,跟踪的下载进度在PHP
我建立了一个表格,如果用户在填写表单,我的代码可以决定需要什么(大)文件由该用户下载。我使用下载按钮显示每个文件,并且我想显示该按钮旁边该文件的下载状态(正在下载,正在取消/中止或完成)。由于文件很大(200 MB +),我使用一个众所周知的功能来读取要在chunck中下载的文件。 我的想法是记录数据库中每个(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 k个块由PHP提供)长达一分钟(这个超时取决于可用于下载的带宽)。事实上,没有进展是写一分钟,使我的代码相信下载被中止。在此期间,我看到IIS的内存使用量在不断增加,所以我得到了IIS缓冲PHP提供的大量数据的想法。 我的网络服务器在FastCGI模式下运行Windows 2008 R2数据中心(64位),IIS 7.5和PHP 5.3.8。有什么我可以做的(在我的代码中,在我的PHP配置中或在IIS配置中)防止IIS缓存PHP提供的数据,或者如果生成的数据实际传递到下载客户端? 在此先感谢!
我问了一个similar question一次,并得到了非常好的结果与答案。
基本上,您使用APC缓存来缓存变量,然后使用来自客户端的Ajax调用在不同的页面中检索它。
另一种可能性是对数据库也这样做。将进度写入数据库,并让客户端使用Ajax调用来测试(假设每秒)。
由于没有有用的答案出现,我创建了一个真正的狡猾的解决方法,严格使用Apache来下载文件。整个表单,CSS等仍然通过IIS提供,只是下载链接由Apache服务器(反向代理服务器位于两者之间,因此用户无需摆弄端口号,代理服务器负责此操作)。 Apache不会缓存PHP输出,所以我在数据库中获得的时间戳是可靠的。
从PHP下载取得进展是不可能的:) – OptimusCrime 2012-04-13 09:37:49
@OptimusCrime:错误。使用数据库写入状态,并使用Ajax读取它。也许使用APC。 – 2012-04-13 09:41:05
@OptimusCrime - 它是如果你做什么操作系统正在做的事情,通过将文件分解成单独的部分,并记录每个部分交付 – BenOfTheNorth 2012-04-13 09:41:28