2014-12-17 24 views
11

Ho il seguente scenario: È possibile scaricare dal nostro server alcuni file. Se sei un utente "normale", hai una larghezza di banda limitata, ad esempio 500 kbit. Se sei un utente premium, non hai un limite di larghezza di banda e puoi scaricare il più velocemente possibile. Ma come posso rendermene conto? Come viene caricato questo &?PHP/Javascript: come posso limitare la velocità di download?

+0

Buona domanda, ha bisogno di una buona risposta. – Timtech

+0

possibile duplicato di [Limita velocità download tramite PHP] (http://stackoverflow.com/questions/4002106/limit-download-speed-using-php) –

+0

@OleHaugset Non la stessa domanda, le risposte non si applicano a questa domanda . – Alfabravo

risposta

6

Nota: è possibile farlo con PHP, ma vi consiglio di lasciare che il server stesso gestisce strozzamento. La prima parte di questa risposta riguarda le opzioni disponibili se desideri limitare la velocità di download con PHP da solo, ma di seguito troverai un paio di link in cui troverai come gestire i limiti di download utilizzando il server.

C'è un'estensione PECL che rende questo un compito piuttosto banale, chiamato pecl_http, che contiene la funzione http_throttle. I documenti contengono un semplice esempio di come farlo già. Questa estensione contiene anche a HttpResponse class, che non è ATM ben documentato, ma sospetto che giocare con i suoi metodi setThrottleDelay e setBufferSize dovrebbe produrre il risultato desiderato (ritardo di accelerazione => 0,001, dimensione del buffer 20 == ~ 20 KB/sec). Dalla bellezza di cose, questo dovrebbe funzionare:

$download = new HttpResponse(); 
$download->setFile('yourFile.ext'); 
$download->setBufferSize(20); 
$download->setThrottleDelay(.001); 
//set headers using either the corresponding methods: 
$download->setContentType('application/octet-stream'); 
//or the setHeader method 
$download->setHeader('Content-Length', filesize('yourFile.ext')); 
$download->send(); 

Se non è possibile/non si desidera installare che, è possibile scrivere un semplice ciclo, però:

$file = array(
    'fname' => 'yourFile.ext', 
    'size' => filesize('yourFile.ext') 
); 
header('Content-Type: application/octet-stream'); 
header('Content-Description: file transfer'); 
header(
    sprintf(
     'Content-Disposition: attachment; filename="%s"', 
     $file['fname'] 
    ) 
); 
header('Content-Length: '. $file['size']); 
$open = fopen($file['fname'], "rb"); 
//handle error if (!$fh) 
while($chunk = fread($fh, 2048))//read 2Kb 
{ 
    echo $chunk; 
    usleep(100);//wait 1/10th of a second 
} 

Naturalmente , non bufferizzare l'output se lo fai :), e potrebbe essere meglio aggiungere anche un'istruzione set_time_limit(0);. Se il file è grande, è molto probabile che lo script venga ucciso a metà del download, perché raggiunge il tempo massimo di esecuzione.

Altro (e probabilmente preferibile) approccio sarebbe quello di limitare la velocità di download attraverso la configurazione del server:

Non ho mai limitato le tariffe di download, ma guardando il link s, credo che sia giusto dire che nginx è il più facile di gran lunga:

location ^~ /downloadable/ { 
    limit_rate_after 0m; 
    limit_rate 20k; 
} 

Questo rende il limite calcio tasso immediatamente, e lo imposta a 20k.Dettagli possono essere trovati su the nginx wiki.

Per quanto Apache è interessato, non è che molto più difficile, ma ti richiedono di attivare il modulo ratelimit

LoadModule ratelimit_module modules/mod_ratelimit.so 

Quindi, si tratta di una semplice questione di apache dire quali file devono essere strozzata:

<IfModule mod_ratelimit.c> 
    <Location /downloadable> 
     SetOutputFilter RATE_LIMIT 
     SetEnv rate-limit 20 
    </Location> 
</IfModule> 
1

È possibile utilizzare http_throttle dall'estensione pecl_http PHP:

<?php 
// ~ 20 kbyte/s 
# http_throttle(1, 20000); 
# http_throttle(0.5, 10000); 
if (!$premium_user) { 
    http_throttle(0.1, 2000); 
} 
http_send_file('document.pdf'); 
?> 

(. La si basa soprattutto su un esempio da http://php.net/manual/en/function.http-throttle.php)

Se l'API server non consente http_throttle creare due distinte, URL non raccomandabili per gli utenti premium e non premium e fare riferimento alla documentazione del server HTTP su come limitare uno di essi. Vedere https://serverfault.com/questions/179646/nginx-throttle-requests-to-prevent-abuse per un esempio per Nginx. Quest'ultimo ha il vantaggio di permetterti di aggirare problemi come i download che vengono interrotti presto a causa dell'uccisione di PHP del tuo script.

0

C'è questa libreria terra utente PHP bandwidth-throttle/bandwidth-throttle

use bandwidthThrottle\BandwidthThrottle; 

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

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

stream_copy_to_stream($in, $out); 
Problemi correlati