![](/img/trans.png)
[英]Is there a way with PHP to access a file on a server and save only the first half of the file?
[英]PHP only half of file is downloaded
我有一些较大的文件需要与人们分享并让他们更容易(以及开发它的乐趣)我正在开发一个基于浏览器的小型 FTP 客户端。 无非就是PHP中的标准功能。
昨天我在这里提出了一个关于如何将 AVI 文件下载到客户端的问题,我发现这个 function可以这样做:
<?php
/* Tutorial by AwesomePHP.com -> www.AwesomePHP.com */
/* Function: download with resume/speed/stream options */
/*
Parametrs: downloadFile(File Location, File Name,
max speed, is streaming
If streaming - movies will show as movies, images as images
instead of download prompt
*/
function downloadFile($fileLocation,$fileName,$maxSpeed = 100,$doStream =
false){
if (connection_status()!=0) return(false);
$extension = strtolower(end(explode('.',$fileName)));
/* List of File Types */
$fileTypes['swf'] = 'application/x-shockwave-flash';
$fileTypes['pdf'] = 'application/pdf';
$fileTypes['exe'] = 'application/octet-stream';
$fileTypes['zip'] = 'application/zip';
$fileTypes['doc'] = 'application/msword';
$fileTypes['xls'] = 'application/vnd.ms-excel';
$fileTypes['ppt'] = 'application/vnd.ms-powerpoint';
$fileTypes['gif'] = 'image/gif';
$fileTypes['png'] = 'image/png';
$fileTypes['jpeg'] = 'image/jpg';
$fileTypes['jpg'] = 'image/jpg';
$fileTypes['rar'] = 'application/rar';
$fileTypes['ra'] = 'audio/x-pn-realaudio';
$fileTypes['ram'] = 'audio/x-pn-realaudio';
$fileTypes['ogg'] = 'audio/x-pn-realaudio';
$fileTypes['wav'] = 'video/x-msvideo';
$fileTypes['wmv'] = 'video/x-msvideo';
$fileTypes['avi'] = 'video/x-msvideo';
$fileTypes['asf'] = 'video/x-msvideo';
$fileTypes['divx'] = 'video/x-msvideo';
$fileTypes['mp3'] = 'audio/mpeg';
$fileTypes['mp4'] = 'audio/mpeg';
$fileTypes['mpeg'] = 'video/mpeg';
$fileTypes['mpg'] = 'video/mpeg';
$fileTypes['mpe'] = 'video/mpeg';
$fileTypes['mov'] = 'video/quicktime';
$fileTypes['swf'] = 'video/quicktime';
$fileTypes['3gp'] = 'video/quicktime';
$fileTypes['m4a'] = 'video/quicktime';
$fileTypes['aac'] = 'video/quicktime';
$fileTypes['m3u'] = 'video/quicktime';
$contentType = $fileTypes[$extension];
header("Cache-Control: public");
header("Content-Transfer-Encoding: binary\n");
header('Content-Type: $contentType');
$contentDisposition = 'attachment';
if($doStream == true){
/* extensions to stream */
$array_listen = array('mp3','m3u','m4a','mid','ogg','ra','ram','wm',
'wav','wma','aac','3gp','avi','mov','mp4','mpeg','mpg','swf','wmv','divx','asf');
if(in_array($extension,$array_listen)){
$contentDisposition = 'inline';
}
}
if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE")) {
$fileName= preg_replace('/\./', '%2e', $fileName, substr_count($fileName,
'.') - 1);
header("Content-Disposition: $contentDisposition;
filename=\"$fileName\"");
} else {
header("Content-Disposition: $contentDisposition;
filename=\"$fileName\"");
}
header("Accept-Ranges: bytes");
$range = 0;
$size = filesize($fileLocation);
if(isset($_SERVER['HTTP_RANGE'])) {
list($a, $range)=explode("=",$_SERVER['HTTP_RANGE']);
str_replace($range, "-", $range);
$size2=$size-1;
$new_length=$size-$range;
header("HTTP/1.1 206 Partial Content");
header("Content-Length: $new_length");
header("Content-Range: bytes $range$size2/$size");
} else {
$size2=$size-1;
header("Content-Range: bytes 0-$size2/$size");
header("Content-Length: ".$size);
}
if ($size == 0 ) { die('Zero byte file! Aborting download');}
set_magic_quotes_runtime(0);
$fp=fopen("$fileLocation","rb");
fseek($fp,$range);
while(!feof($fp) and (connection_status()==0))
{
set_time_limit(0);
print(fread($fp,1024*$maxSpeed));
flush();
ob_flush();
sleep(1);
}
fclose($fp);
return((connection_status()==0) and !connection_aborted());
}
/* Implementation */
downloadFile('fileLocation','fileName.ext',900,false);
?>
现在我的问题是,当下载大文件(大约 800 MB)时,我只得到一半的文件(大约 440 MB),我不知道为什么会这样。 谁能告诉我我做错了什么,或者有人知道我可以做些什么不同的事情吗?
如前所述,我将这个 function与下面的脚本结合使用。
require_once 'func_downloadFile.php';
// Get filename
$filename = explode("/", $_GET['file']);
$filename = $filename[count($filename)-1];
$file_path = "downloads/" . $filename;
if(file_exists($file_path)) {
downloadFile($file_path, $filename, 900, false);
}
else {
echo "File does not exist.";
}
首先,文件从我的 NAS 下载到我的网络服务器,然后发送到客户端。 如果我使用我的脚本下载到客户端,我只会得到一半的文件,但如果我将文件从我的 NAS 下载到我的网络服务器,然后通过 FTP 客户端登录到 tmy 网络服务器并下载文件,我会得到整个文件。 所以问题是从网络服务器发送到客户端时(这就是downloadFile()
所做的)
编辑:我尝试使用if(ini_get('safe_mode')){
检查safe_mode
是否打开,它返回 false。 因此,我尝试添加以下两行以将超时设置为无限制,但结果是相同的。
ini_set('max_execution_time', 0);
set_time_limit(0);
您是否有可能达到脚本执行时间限制? (默认 30 秒)
您可以编辑 function 以重置循环中的时间限制...
while(!feof($fp) and (connection_status()==0)) {
set_time_limit(30);
...
}
如果不编辑 php.ini,则无法将限制设置得更高,但是将其放入循环中将在循环的每次迭代中将其重置。
httpd 错误日志中是否有任何条目?
尝试更改您的超时设置。 该条目名为max_execution_time ,您可以在 php.ini 文件中找到它。 标准是 30 秒。 (set_time_limit 在安全模式下不起作用)
set_time_limit 将允许您调整脚本的最大执行时间,请参阅http://php.net/manual/en/function.set-time-limit.php
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.