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

readfile "memory issue"?

vit_o

Neues Mitglied
Frohe Weihnachten! :)
Ich hab ein Problem beim downloaden von großen Dateien (20MB), deren download mit einem php-Script gestartet wird. Bis vor kurzem hat alles noch funktioniert auch für große Dateien. Jetzt bricht PHP ohne Fehlermeldung bei dem Befehl readfile ab, selbst, wenn die Fehlermeldungen eingeschaltet sind. Für kleine Dateien funktioniert immer noch alles bestens. Am Programm habe ich nichts verändert und mein Provider sagt, dass sich die Servereinstellungen auch nicht geändert haben.
Ein Blick in die php-doku sagt, "readfile will not present any memory issues". Heißt das also, dass der zugewisesene Arbeitsspeicher zu klein ist?
 
Werbung:
kannst du deinen code posten? ist das problem permanent oder sporadisch? nimmt dein webspace ein "php_value memory_limit 128M" in der .htaccess, oder bekommst du einen 500er ? was sagt deine phpinfo zum memory limit?
 
Das Problem besteht permanent für große Dateien. Für kleine funktioniert es auch dauerhaft.
Ich bekomme einen 500 Internal Server Error wenn PHP Fehlermeldungen abgestellt sind und bekomme eine leere Datei (ohne Fehlermeldung) wenn die PHP-Fehlermeldungen eingeschaltet sind.
Das PHP-Memory-Limit kann ich leider nicht beeinflussen.
PHP-Info liefert 24M memory limit. (Aber selbst 14 MB können nicht mehr downgeloaded werden)

PHP:
if(!empty($name) && is_file($filename)){
    //generate filename
    if(!empty($sermon)){
        $saveAs    = date('d.m.y', $sermon->date).' '.$sermon->title.strrchr($name, '.');
    }else{
        $saveAs    = 'Unbekannte Predigt'.strrchr($name, '.');
    }
    //return file;
    header("Content-Type: application/octet-stream");
    header("Content-Disposition: attachment; filename=\"".$saveAs."\"");
    header("Content-Length: ".filesize($filename));
    readfile($filename);
    die();//force end
}else{
    echo "Die gewünschte Datei ist nicht verfügbar!";
}
 
Werbung:
versuchs mal so, das funktioniert für 24M memory limit:
(da gehen dateien mit 100mb+ durch)

PHP:
<?php
$filename = $_GET['s'];

header ("HTTP/1.1 200 OK");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$filename."\"");
header("Content-Length: ".filesize($filename));

$size = 1048576;
$file = fopen($filename, 'rb');
while (!feof($file))
{
    echo fread($file, $size);
    ob_flush();
    flush();
}
fclose($handle);
?>


EDIT: das ganze zieht sich ~8MB für die dauer... sollte für deine zwecke ausreichen
 
Zuletzt bearbeitet von einem Moderator:
versuchs mal so, das funktioniert für 24M memory limit:
(da gehen dateien mit 100mb+ durch)

PHP:
<?php
$filename = $_GET['s'];

header ("HTTP/1.1 200 OK");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$filename."\"");
header("Content-Length: ".filesize($filename));

$size = 1048576;
$file = fopen($filename, 'rb');
while (!feof($file))
{
    echo fread($file, $size);
    ob_flush();
    flush();
}
fclose($handle);
?>


EDIT: das ganze sieht sich ~8MB für die dauer... sollte für deine zwecke ausreichen

Würdest du wirklich eine Datei MB für MB auslesen? Da bedankt sich dein PHP-Script aber.
 
das möcht ich auch hoffen! ich würde ihm nie ein file_get_contents über die 100mb zumuten ;) 100mb aufeinmal in einer variable wärn echt zuviel.


edit: das ganze läuft unter dem namen chunked readfile, auch wenn das transfer encoding hier nicht mit chunked angegeben wird.
mit readfile komm ich nicht klar, wenn da jemand ne lösung weiß, gerne :) erhalte dateien mit 0 oder 150bytes... je nach memory limit. das erschließt sich mir noch nicht.
 
Zuletzt bearbeitet von einem Moderator:
Werbung:
Das Funktioniert super! Aber warum funktioniert es mit readfile nicht?
Ich habe mein Skript auf nem anderen Server mal ausprobiert und dort klappt es mit readfile auch für größere Dateien super. Aber vielen Dank für den Tipp es schrittweise zu machen!
 
Zuletzt bearbeitet:
ich denke nicht, dass du durch die chunked variante nachteile haben wirst. 8mb bei 100mb download sollten jetzt nich allzuviel sein bei meiner recherche zu readfile und niedrigem memory limit, haben leute von ram belastung durch readfile berichtet. so wie ich die sache verstanden habe, wird durch readfile keine php variable mit dem inhalt gefüllt, dieser overhead entsteht bei einer variante mit fopen oder file_get_contents.
hier haben sich die leute auch gedanken dzau gemacht: Why does readfile() exhaust PHP memory? - Stack Overflow

8mb absolute mehr belastung (gemessen auf meinem nas mit insgesammt 128mb) halte ich für gering genug bei einem 100mb download. zum vergleich: ein oxid shop frisst zeitweise mehr als 64M (setze hier 128M) bei einem bildupload von ca 5mb. auch readfile kommt um ein stückweise lesen der datei nicht herum, weil es technisch nicht anders möglich ist. letztendlich landet die datei zerstückelt in kleinen datenpaketen auf dem weg zum client.

ein setzen von chunked encoding hätte zur folge, dass der server vorab kein ende der datei angibt. er streamt einfach daten. bei dem script wird die filesize gesetzt und der effekt ist zwar chunked aber für den client ist das ganze ein ganz normaler download.
 
Zuletzt bearbeitet von einem Moderator:
Zurück
Oben