全部,
我已经建立了一个表格,如果用户填写表格,我的代码可以确定该用户需要下载哪些(大)文件。我用下载按钮显示每个文件,我想在按钮旁边显示该文件的下载状态(下载正在进行、取消/中止或完成)。因为文件很大(200 MB+),所以我使用一个众所周知的函数来读取要以块下载的文件。我的想法是记录数据库中每个(100 KB)块的读取,这样我就可以跟踪下载进度。我的代码如下:
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 KB 块),下一刻我看到没有数据库更新(因此 PHP 没有提供 100 k 块)长达一分钟(此超时取决于可用于下载的带宽)。一分钟内没有写入任何进度的事实使我的代码认为下载已中止。与此同时,我看到 IIS 的内存使用量在增加,因此我认为 IIS 会缓冲 PHP 提供的数据块。我的网络服务器在 FastCGI 模式下运行 Windows 2008 R2 数据中心(64 位)、IIS 7.5 和 PHP 5.3.8。有什么我可以做的(在我的代码中,在我的 PHP 配置或 IIS 配置中)以防止 IIS 缓存 PHP 传递的数据,或者如果生成的数据实际传递到下载客户端,是否有任何方法可以在 PHP 中查看?提前致谢!