2010-10-23 40 views
14

Encontré en Google algunos scripts PHP para limitar la velocidad de descarga de un archivo, pero el archivo se descarga a 10 Mbps o si se descarga a 80 kbps cuando lo configuro, después de 5 mb, deja de descargarse .Limite la velocidad de descarga usando PHP

¿Puede alguien decirme dónde puedo encontrar un buen script de límite de velocidad de descarga de PHP, por favor?

Muchas gracias

--- --- Editar

Aquí está el código:

<?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

debe utilizar 'echo' en lugar de' print', es ligeramente más rápido – FluorescentGreen5

+0

Gracias por la punta! –

Respuesta

16

La razón por la descarga se detiene después de 5 MB es porque tarda más de 60 segundos para descargar 5MB a 80KB/s. La mayoría de esos scripts de "limitador de velocidad" usan sleep() para hacer una pausa por un tiempo después de enviar un fragmento, reanudar, enviar otro fragmento y pausar nuevamente. Pero PHP terminará automáticamente una secuencia de comandos si se ha estado ejecutando durante un minuto o más. Cuando eso sucede, la descarga se detiene.

Puede usar set_time_limit() para evitar que su script finalice, pero algunos servidores web no le permitirán hacerlo. En ese caso, no tienes suerte.

+0

Si pongo set_time_limit (0); al comienzo de mi script, no limita la velocidad: S .. Ver la publicación original para el código PHP. –

+6

No veo cómo usar set_time_limit() evitaría que su script limitara las velocidades de descarga. Todo lo que debe hacer es evitar que el script se agote. El corazón de su script es la función sleep(), que no tiene nada que ver con set_time_limit(). – mellowsoon

+0

Utilicé set_time_limit causa después de 60 segundos mi descarga detener ... :( –

9

Un segundo es demasiado tiempo, hará que los clientes piensen que el servidor no responde y terminará prematuramente la descarga. Cambio 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

probé mi mano en una clase personalizada que pueden ayudarle a lidiar con la tasa de descargas limitante, puede probar con el siguiente?

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. 
    } 
    } 

He alojado el archivo como una esencia en github aquí. - https://gist.github.com/3687527

1

La clase Downloader es buena, pero tiene un problema si tiene dos descargas al mismo tiempo, perderá el valor max_execution_time.

Algunos ejemplos:

Descargar primer archivo (tamaño = 1 mb; descarga a tiempo de 100 segundos)

después de la segunda un archivo de segunda descarga (tamaño = 100 mb; dowload tiempo = 10000 segundos)

primero descarga Establecer max_execution_time a 0

Segunda remeber _oldMaxExecTime como 0

primera do wnload final y volver max_execution_time al valor antiguo

El segundo extremo de descarga y volver max_execution time a 0

+1

Thansk para obtener información valiosa Kalanj! –

0

Primera de todos max_execution_time es el tiempo de ejecución de su script. Dormir no es parte de eso.

En cuanto a la limitación de la velocidad, puede utilizar algo así como un depósito Token. He puesto todo en una biblioteca conveniente para usted: 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); 
Cuestiones relacionadas