2010-10-23 20 views
14

Ho trovato su Google alcuni script PHP per limitare la velocità di download di un file, ma il download del file a 10 Mbps o se scarica a 80 kbps come lo imposto, dopo 5 mb, smette di scaricare .Limitare la velocità di download usando PHP

Qualcuno può dirmi dove posso trovare un buon script di limite di velocità di download PHP, per favore?

La ringrazio molto

--- --- Modifica

Ecco il codice:

<?php 
set_time_limit(0); 
// change this value below 
$cs_conn = mysql_connect('localhost', 'root', ''); 
mysql_select_db('shareit', $cs_conn); 

// local file that should be send to the client 
$local_file = $_GET['file']; 
// filename that the user gets as default 
$download_file = $_GET['file']; 

// set the download rate limit (=> 20,5 kb/s) 
$download_rate = 85; 
if(file_exists($local_file) && is_file($local_file)) { 
    // send headers 
    header('Cache-control: private'); 
    header('Content-Type: application/octet-stream'); 
    header('Content-Length: '.filesize($local_file)); 
    header('Content-Disposition: filename='.$download_file); 

    // flush content 
    flush();  
    // open file stream 
    $file = fopen($local_file, "r");  
    while(!feof($file)) { 

     // send the current file part to the browser 
     print fread($file, round($download_rate * 1024));  

     // flush the content to the browser 
     flush(); 

     // sleep one second 
     sleep(1);  
    }  

    // close file stream 
    fclose($file);} 
else { 
    die('Error: The file '.$local_file.' does not exist!'); 
} 




if ($dl) { 
} else { 
    header('HTTP/1.0 503 Service Unavailable'); 
    die('Abort, you reached your download limit for this file.'); 
} 
?> 
+0

si dovrebbe usare 'echo' invece di' print', è leggermente più veloce – FluorescentGreen5

+0

Grazie per la punta! –

risposta

16

Il motivo per il download si interrompe dopo 5 MB è perché ci vuole più di 60 secondi per Scarica 5 MB a 80 KB/s. La maggior parte di questi script "limitatore di velocità" utilizza sleep() per mettere in pausa per un po 'dopo l'invio di un blocco, riprendere, inviare un altro blocco e mettere nuovamente in pausa. Ma PHP terminerà automaticamente uno script se è in esecuzione da un minuto o più. Quando ciò accade, il download si interrompe.

È possibile utilizzare set_time_limit() per impedire la terminazione dello script, ma alcuni host Web non consentono di farlo. In tal caso sei sfortunato.

+0

Se metto set_time_limit (0); all'inizio del mio script, non limita la velocità: S .. Vedi il post originale per il codice PHP. –

+6

Non vedo come utilizzare set_time_limit() possa impedire al tuo script di limitare la velocità di download. Tutto ciò che dovrebbe fare è evitare che la sceneggiatura vada in time out. Il cuore del tuo script è la funzione sleep(), che non ha nulla a che fare con set_time_limit(). – mellowsoon

+0

Ho usato set_time_limit perché dopo 60 secondi il mio download si interrompe ... :( –

9

Un secondo è troppo tempo, farà pensare ai client che il server non risponde e interrompe prematuramente il download. Change sleep(1)-usleep(200):

set_time_limit(0); 

$file = array(); 
$file['name'] = 'file.mp4'; 
$file['size'] = filesize($file['name']); 

header('Content-Type: application/octet-stream'); 
header('Content-Description: file transfer'); 
header('Content-Disposition: attachment; filename="' . $file['name'] . '"'); 
header('Content-Length: '. $file['size']); 

$open = fopen($file['name'], 'rb'); 
while(!feof($open)){ 
    echo fread($open, 256); 
    usleep(200); 
} 
fclose($open); 
0

ho provato la mia mano a una classe personalizzata che può aiutare a trattare con limitazione della velocità di download, si può provare il seguente?

class Downloader { 
    private $file_path; 
    private $downloadRate; 
    private $file_pointer; 
    private $error_message; 
    private $_tickRate = 4; // Ticks per second. 
    private $_oldMaxExecTime; // saving the old value. 
    function __construct($file_to_download = null) { 
     $this->_tickRate = 4; 
     $this->downloadRate = 1024; // in Kb/s (default: 1Mb/s) 
     $this->file_pointer = 0; // position of current download. 
     $this->setFile($file_to_download); 
    } 
    public function setFile($file) { 
     if (file_exists($file) && is_file($file)) 
      $this->file_path = $file; 
     else 
      throw new Exception("Error finding file ({$this->file_path})."); 
    } 
    public function setRate($kbRate) { 
     $this->downloadRate = $kbRate; 
    } 
    private function sendHeaders() { 
     if (!headers_sent($filename, $linenum)) { 
      header("Content-Type: application/octet-stream"); 
      header("Content-Description: file transfer"); 
      header('Content-Disposition: attachment; filename="' . $this->file_path . '"'); 
      header('Content-Length: '. $this->file_path); 
     } else { 
      throw new Exception("Headers have already been sent. File: {$filename} Line: {$linenum}"); 
     } 
    } 
    public function download() { 
     if (!$this->file_path) { 
      throw new Exception("Error finding file ({$this->file_path})."); 
     } 
     flush();  
     $this->_oldMaxExecTime = ini_get('max_execution_time'); 
     ini_set('max_execution_time', 0); 
     $file = fopen($this->file_path, "r");  
     while(!feof($file)) { 
      print fread($file, ((($this->downloadRate*1024)*1024)/$this->_tickRate);  
      flush(); 
      usleep((1000/$this->_tickRate)); 
     }  
     fclose($file); 
     ini_set('max_execution_time', $this->_oldMaxExecTime); 
     return true; // file downloaded. 
    } 
    } 

Ho ospitato il file come addio e github qui. - https://gist.github.com/3687527

1

La classe di download è buona ma ha un problema se si hanno due download contemporaneamente, si perderà il valore max_execution_time.

Qualche esempio:

Scarica primo file (size = 1 MB; tempo di download di 100 secondi)

dopo un secondo scaricare secondo file (size = 100 MB; dowload tempo = 10000 secondi)

in primo luogo scaricare impostato max_execution_time-0

seconda ricordate _oldMaxExecTime come 0

prima fare wnload fine e tornare max_execution_time al vecchio valore

seconda estremità scaricare e tornare max_execution time-0

+1

Grazie per le preziose informazioni Kalanj! –

0

First di tutti max_execution_time è il tempo di esecuzione del tuo script. Dormire non fa parte di esso.

Per quanto riguarda la limitazione della velocità, è possibile utilizzare qualcosa come un bucket Token. Ho messo tutto in una libreria conveniente per voi: bandwidth-throttle/bandwidth-throttle

use bandwidthThrottle\BandwidthThrottle; 

$in = fopen(__DIR__ . "/resources/video.mpg", "r"); 
$out = fopen("php://output", "w"); 

$throttle = new BandwidthThrottle(); 
$throttle->setRate(100, BandwidthThrottle::KIBIBYTES); // Set limit to 100KiB/s 
$throttle->throttle($out); 

stream_copy_to_stream($in, $out); 
Problemi correlati