在我的php应用程序中我想使用“stream_copy_to”从互联网上下载文件,但由于文件可能很长,我想在javascript进度条中保持跟踪进度。我怎样才能做到这一点 ?有什么想法吗?
答案 0 :(得分:1)
您可以将事件数据存储在数据库表中,并且在复制运行时,您可以向php脚本发出AJAX请求以返回进度:
stream_copy_to_stream
而是使用循环一次复制小块,定期更新数据库中的bytes_received列一般方法
在启动stream_copy_to_stream
之前,您将获得Content-Length
标头(如果可用)并将其存储在数据库表或其他表中以供将来比较。
执行stream_copy_to_stream
时,对php脚本使用AJAX请求,将输出文件大小与内容长度进行比较,并返回进度条中使用的百分比。
$sourceFile = 'your-source-file';
$destFile = 'your-destination-file-name';
$source = fopen($sourceFile, 'r');
$headers = parseHeaders(stream_get_meta_data($source)['wrapper_data']);
if ($headers['response_code'] == 200 && isset($headers['Content-Length']))
{
// insert $destFile, $headers['Content-Length'] into database
// return the ID to frontend for progress checks
}
$dest = fopen($destFile, 'w');
stream_copy_to_stream($source, $dest);
您可以使用此类函数来解析标题
function parseHeaders($headers)
{
$head = array();
foreach( $headers as $k=>$v )
{
$t = explode(':', $v, 2);
if (isset($t[1] ))
$head[trim($t[0])] = trim($t[1]);
else
{
$head[] = $v;
if(preg_match("#HTTP/[0-9\.]+\s+([0-9]+)#",$v,$out))
$head['reponse_code'] = intval($out[1]);
}
}
return $head;
}
前端您将触发AJAX请求以启动副本,该请求将返回ID和Content-Length信息以设置进度条。
当副本运行时,会在一段时间内触发一个AJAX请求来检查进度并更新进度条。
// get the file information from the database based on the ID
// $totalSize = Content-Length data from database
$currentSize = filesize($destFile);
$progress = min(100, 100 * $currentSize / $totalSize);
echo json_encode(array('progress' => $progress));