PHP только половина файла загружена - PullRequest
0 голосов
/ 18 июля 2011

У меня есть файлы большего размера, которые я хочу поделиться с людьми, чтобы им было легче (и для удовольствия разработать). Я занимаюсь разработкой небольшого FTP-клиента на основе браузера.Это не что иное, как стандартные функции в PHP.

Вчера я задал здесь вопрос о том, как загрузить AVI-файлы на клиент , и нашел этофункция для этого:

<?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 МБ) я получаю только половину файла (около 440 МБ), и я понятия не имею, почемуэто.Может кто-нибудь сказать мне, что я делаю неправильно, или у кого-то есть идеи, что я могу сделать по-другому?

Как уже упоминалось, я использую эту функцию в сочетании с моим сценарием ниже.

    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 на свой веб-сервер, затем регистрируюсь на tmy webserver через FTP-клиент и загружаю файл, я получу весь файлфайл.Поэтому проблема заключается в отправке с веб-сервера клиенту (что и делает downloadFile())

РЕДАКТИРОВАТЬ: Я пытался проверить, было ли safe_mode при использовании if(ini_get('safe_mode')){, который возвратил false.Поэтому я попытался добавить две строки ниже, чтобы установить неограниченное время ожидания, но результат тот же.

ini_set('max_execution_time', 0);
set_time_limit(0);

Ответы [ 3 ]

1 голос
/ 18 июля 2011

Попробуйте изменить настройки тайм-аута. Запись называется max_execution_time , и вы можете найти ее в файле php.ini. Стандарт составляет 30 секунд. (set_time_limit не будет работать в безопасном режиме)

1 голос
/ 18 июля 2011

Возможно ли, что вы достигли ограничения по времени выполнения скрипта? (По умолчанию 30 секунд)

Вы можете редактировать свою функцию, чтобы сбросить ограничение по времени в цикле ...

while(!feof($fp) and (connection_status()==0)) {
    set_time_limit(30); 
    ...
}

Вы не можете установить предел выше, не редактируя php.ini, но если поместить его в цикл, он будет сбрасываться на каждой итерации цикла.

Есть ли записи в журнале ошибок httpd?

0 голосов
/ 18 июля 2011

set_time_limit позволит вам настроить максимальное время выполнения скрипта, см. http://php.net/manual/en/function.set-time-limit.php

...