2013-02-01 7 views
5

Ich schreibe ein Skript, das eine Datei von einer Webadresse über meinen Server an den Benutzer streamen wird. In seinem aktuellen Zustand funktioniert es, aber es ist sehr langsam.Streaming einer Datei aus dem Internet über PHP ist langsam

Hier ist der entsprechende Code:

/* Bytes per second */ 
define('TRANSFER_CAP', 1048576); 

/* Hard part... stream the file to the user */ 
header('Content-Description: File Transfer'); 
header('Content-Disposition: attachment; filename=' . $filename); 
header('Content-Transfer-Encoding: binary'); 
header('Content-Length: ' . $filesize); 

$file = fopen($fileLocation, 'rb'); 
if(!$file) { 
    // TODO: handle errors 
} 

while(!feof($file)) { 
    echo fread($file, TRANSFER_CAP/2); 
    ob_flush(); 
    flush(); 

    /* Limit the download speed by sleeping */ 
    usleep(500); 
} 

Dieses Skript auf meinem lokalen Rechner ausgeführt wird. Wenn ich die Datei in meinem Browser anfordere (nicht durch das Skript), bekomme ich eine solide Download-Geschwindigkeit von ca. 2,5MB/s, was die maximale Geschwindigkeit meines Internets ist. Wenn ich das Skript jedoch ausführe und versuche, dieselbe Datei herunterzuladen, erhalte ich nur 240-250 KB/s.

Ich weiß, es ist nicht das Skript, das die Übertragungsgeschwindigkeit begrenzt, weil ich es auf 1MB/s eingestellt habe. Ich kann mir auch nichts in diesem Skript vorstellen, das einen großen Overhead erzeugt, der die Geschwindigkeit verlangsamen würde.

Edit: Etwas interessant, wenn ich das mit readfile() stattdessen bekomme ich fast meine volle Download-Geschwindigkeit:

readfile('http://cachefly.cachefly.net/100mb.test'); 

so muss es ein Problem mit fopen und fread mit?

+0

Ihre Upload-Geschwindigkeit die gleiche wie Sie herunterladen? In vielen Orten der Welt sind sie nicht. Du kannst http://speedtest.net testen. –

+0

Es ist nicht, aber ich lade in diesem Skript nichts hoch. Ich lade die Datei einfach herunter, aber aus irgendeinem Grund ist es viel langsamer als wenn ich die Datei direkt über meinen Browser herunterlade. –

+0

Entschuldigung missverstanden. Wenn es keine große Datei ist, versuchen Sie \t file_get_contents() statt –

Antwort

0

Warum machen Sie nicht einfach eine HTTP-Header-Umleitung zur Binärdatei selbst? Auf diese Weise nehmen Sie die PHP aus der Gleichung alle zusammen, da alles, was Sie tun möchten, ist, die Datei zu bedienen.

+0

Wenn ich das machen würde, würde ich direkt zum Dateidownload anstatt über ein PHP-Skript verlinken.Ich muss es aus ein paar Gründen so machen, einschließlich der Überwachung, wie viel ein Benutzer herunterlädt. Auf diese Weise kann ich "die Bytes zählen" und eine genaue Summe erhalten. –

+0

Warum nicht ein "include" irgendeiner Art von PHP, um die Binärdaten zu senden anstatt Daten in Blöcken zu lesen und zu senden? Ich denke nur laut nach. –

0

Im Grunde erstellen Sie einen Proxy-Server mit PHP. Haben Sie darüber nachgedacht, mod_proxy (http://httpd.apache.org/docs/2.2/mod/mod_proxy.html) oder Squid Proxy (http://www.squid-cache.org/)

+0

Das ist keine Option. Obwohl ich konstruiere, was (in seiner Grundform) ein Proxy ist, ändert sich die Variable '$ fileLocation' basierend auf einem API-Aufruf eines Drittanbieters. Die Verwendung eines serverseitigen Proxy-Mods funktioniert nicht. –