• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Auslieferung großer Dateien per PHP

Tobi44

Mitglied
Hallo,

ich lasse User Dateien bis ca. 1 GB herunterladen. Die Dateien werden per PHP ausgeliefert. Häufig kommt es dabei zu folgender Errormeldung: PHP Fatal error: Out of memory (allocated 817102848) (tried to allocate 816246785 bytes)

Vermutlich steht nicht genug RAM zur Verfügung, denn manchmal klappt es, manchmal nicht. Ich muss die Dateien jedoch per PHP ausgeben, da der Direktzugriff per htaccess blockiert wird, da nur bestimmte User die Dateien laden dürfen.
Die Auslieferung erfolgt mittels fopen, fread. Gibt es eine Methode, mit der die Auslieferung in jedem Fall, unabhängig vom verfügbaren Arbeitsspeicher, erfolgt? So ist das Downloadsystem ja unzuverlässig und unzumutbar.

Edit: Ich habe auch schon in der php.ini den Wert von memory_limit auf 2 GB erhöht. Ist das überhaupt relevant? Wenn ja - über 2 GB brauche ich ja eh nicht erhöhen weil er nur 2 GB RAM hat. Richtig?

Alternativ - also sollte es keine andere Möglichkeit geben - kann ich einen Server mit garantiert 2 GB und max. 4 GB RAM bestellen. Der aktuelle hat garantiert 1 GB und max. 2 GB RAM.

Danke
 
Moin,
sowas über php auszugeben ist keine gute idee. Was machst du bei 2 gleichzeitigen Downloads?

Ich würde das immer über direktlinks machen, dazu erstellst du einen temporären symlink auf die Datei, welchen du z.B. nach 10 Stunden mittels cronjob wieder löschst.

MfG
 
2 gleichzeitige Downloads gehen meist nicht. Das ist doof.
Wie soll das mit den Direktlinks gehen? Ich prüfe mittels der ausliefernden PHP-Datei zuvor, ob der User berechtigt ist, zu downloaden. Dies hängt von vielen Faktoren ab.

Evtl. kann man mit PHP die aktuelle Server-Auslastung ausgeben lassen, und im Falle einer zu hohen Auslastung eine entsprechende Meldung anzeigen. Ob das sinnvoll ist, sei mal dahingestellt. Bei einer Website mit einer relativ kleinen Anzahl an Usern durchaus schon. Wie kann ich die Arbeitsspeicherauslastung mit PHP ausgeben? Im Plesk sehe ich sie ja auch...
 
Wenn der User berechtigt ist, zeigst du ihm einen Link zum Download an, und den Rest hat dir Sentence schon geschrieben.
 
Moin,
das geht etwa so:
PHP:
//Verzeichnis welches per http ereichbar ist:
$pubdir = "/home/http_dir/downloads/";

//geheimes verzeichnis, nicht per http erreichbar
$secretdir = "/home/files/"

//Datei die geladen werden soll
$file = "nixfueralle.zip";

//Die URL
$url = "https://example.com/downloads/"

if ($benutzerdarfladen) {
  // wirwarr erzeugen
  $wirrwarr = md5(date());
  //temp verzeichnis erzeugen, naja... 0777 wird wohl nicht benötigt.
  mkdir($pubdir . $wirrwarr, 0777);
  symlink($secretdir . $file, $pubdir . $wirrwarr . "/" . $file);
  header("Location: " . $url . $wirrwarr . "/" . $file);  
}
Dann erzeugst du nen cronjob der alle paar stunden durchläuft, prüft wie alt die temp verzeichnisse sind und diese ggf. löscht.

In der .htaccess (oder http.conf) muss Options +FollowSymLinks aktiviert sein.

Hab das so nicht getestet, sollte aber ein Ansatz für dich sein.

MfG
 
Vielen Dank.

Habe mir nun ein Script gebaut, welches per PHP direkt vom Server ausschließlich die Zahl in Megabyte des verfügbaren Arbeitsspeichers holt. Mit diesem werde ich nun arbeiten und festlegen, dass bei einer bestimmten Unterschreitung anstelle eines PHP-Fatal-errors eine entsprechende Meldung an den User ausgegeben wird. Wenigstens als Übergangslösung.
 
Falls du mit PHP-Sessions oder ähnlicher User-Identifikation arbeitest, könntest du den Symlink auch nach dem Session-Hash benennen.
 
Hallo,

auch wenn mein Beitrag hier schon etwas älter ist: Die m. E. beste Lösung, die ich nun endlich gefunden habe, ist "mod_X-Sendfile" (f. Apache). Nach der Installation aktiviert man es inkl. der Pfade in der Apache-Config und kann dann Dateien per gesendetem Header mit PHP ausgeben (dem Client als Download anbieten zB), auf die sonst kein direkter Zugriff möglich wäre.

Vielleicht hilft es ja einem.

Gruß
 
Zurück
Oben