Allowed memory size exhausted

Alles, was PHP betrifft, kann hier besprochen werden.

Allowed memory size exhausted

Postby spacewalker » 25. July 2013 10:24

Hallo,

ich kann vom Server (V 1.8.2 portable) eine 1GB Datei runterladen..langsam zwar, aber es geht.

Aber bei dem Versuch eine kleinere Datei (500MB) runterzuladen kommt folgender Fehler:
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 521121792 bytes) in C:\xampp\htdocs\login1.php on line 114


OK, ich denke ich muss da in PHP.ini einen memory Wert erhöhen..aber warum kommt diese Meldung bei der kleineren Datei und nicht bei der grossen?
spacewalker
 
Posts: 13
Joined: 25. July 2013 09:46
Operating System: Windows 2008R2

Re: Allowed memory size exhausted

Postby Nobbie » 25. July 2013 11:30

Ohne Kenntnis des Source Codes ist die Frage nicht zu beantworten. Vielleicht macht ja schon login1.php irgendwelche anderen Dinge in Abhängigkeit von Dateigrößen.
Nobbie
 
Posts: 13183
Joined: 09. March 2008 13:04

Re: Allowed memory size exhausted

Postby spacewalker » 25. July 2013 11:51

Nobbie wrote:Ohne Kenntnis des Source Codes ist die Frage nicht zu beantworten. Vielleicht macht ja schon login1.php irgendwelche anderen Dinge in Abhängigkeit von Dateigrößen.


hier mal der Teil des Codes der den Download erledigt:

Code: Select all
...
$fname = basename($_GET["file"]);
DownloadFile ("c://test//" . $fname);
   

exit();

//***************************
function DownloadFile($file)
{ // $file = include path
    if(file_exists($file))
   {
            //echo "starte Download für:[" . $file . "]<br>";
         
      header('Content-Description: File Transfer');
            header('Content-Type: application/octet-stream');
            header('Content-Disposition: attachment; filename='.basename($file));
            header('Content-Transfer-Encoding: binary');
            header('Expires: 0');
            header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
            header('Pragma: public');
            header('Content-Length: ' . filesize($file));
         
            ob_clean();
       //ob_end_flush();  //test memory
         
       flush();
            readfile($file);
            exit;
    }
   else
   {
        die ("Datei nicht gefunden:[" . $file . "]")  ;
   }

}


Der Downloadaufruf sieht dann so aus:
http://myServer/tests/login1.php?file=500MB.iso
spacewalker
 
Posts: 13
Joined: 25. July 2013 09:46
Operating System: Windows 2008R2

Re: Allowed memory size exhausted

Postby Nobbie » 25. July 2013 12:44

Egal warum es bei "kleinen" Dateien knallt - das ist grausam programmiert. So kann man keinen Download programmieren, da wird die ja die komplette Datei in den Serverspeicher geladen. Wieso ist ob_end_flush() auskommentiert?

Ich würde auch den readfile() nicht darauf loslassen, nicht bei so großen Dateien.

P.S.: Was ist denn nun genau die Zeile 114?
Nobbie
 
Posts: 13183
Joined: 09. March 2008 13:04

Re: Allowed memory size exhausted

Postby spacewalker » 25. July 2013 15:02

Nobbie wrote:Egal warum es bei "kleinen" Dateien knallt - das ist grausam programmiert. So kann man keinen Download programmieren, da wird die ja die komplette Datei in den Serverspeicher geladen.

Den Code habe ich irgendwo aus dem Internet, ich selber beschäftige mich erst seit ein paar Tagen mit PHP.

Wieso ist ob_end_flush() auskommentiert?

Ich habe irgendwo gelesen, dass man bei Problemen beim Download den output Buffer abschalten soll..da habe ich etwas expermimentiert...aber es hat nichts gebracht (oder ich habe da einen Fehler gemacht)

Ich würde auch den readfile() nicht darauf loslassen, nicht bei so großen Dateien.


ja, alternativ habe ich noch folgenden code gefunden, der die Datei anscheinend in 4KB Blöcken an den Client sendet.
Wäre vielleicht besser?
Aber auch damit habe ich Probleme: Die Dateien werden nicht vollständig runtergeladen...entweder bricht der Download einfach ab (obwohl ich die max. Skriptlaufzeit auf 10 Minuten gesetzt habe) oder die Dateigrösse der runtergeladenen Datei stimmt zwar mit der Origonaldatei überein - aber die Daten stimmen nicht (Checksumme ist unterschiedlich)
Code: Select all
$Dateiname = basename($Datei);
      $Groesse = filesize($Datei);
      
      $file=fopen($Datei,'r');
      
      //echo "starte Download für:[" . $file . "]<br>";
      
      if ($file) {
        header("Pragma: public");
        header("Expires: 0");
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Cache-Control: private",false);
        header("Content-Type: application/force-download");
        header("Content-Type: application/octet-stream");
        header("Content-Type: application/download");
        header("Content-Disposition: attachment; filename=\"".$Dateiname."\";");
        header("Content-Description: File Transfer");
        header("Content-Transfer-Encoding: binary");
        header('Content-Length: '.$Groesse );
        flush();
        while (!feof($file)) {
          print(fread($file,4096));
          flush();
        }
      }
      fclose($file);
      die("OK");
   }
   else
   {
        die ("Datei nicht gefunden:[" . $Datei . "]")  ;
   }



P.S.: Was ist denn nun genau die Zeile 114?

Readfile

Im Grund möchte ich erreichen, dass der Benutzer auf eine Link klickt, z.b: http://server/login1.php?file=1000.iso, dann nach einem Passwort gefragt wird und dann die Datei runtergeladen wird.
spacewalker
 
Posts: 13
Joined: 25. July 2013 09:46
Operating System: Windows 2008R2

Re: Allowed memory size exhausted

Postby Nobbie » 25. July 2013 15:33

spacewalker wrote:Ich habe irgendwo gelesen, dass man bei Problemen beim Download den output Buffer abschalten soll..da habe ich etwas expermimentiert...aber es hat nichts gebracht (oder ich habe da einen Fehler gemacht


Du hast im Grunde genau das Gegenteil gemacht - statt den Output Buffer abzuschalten, hast Du ihn angelassen, nicht einmal beendet und nun wird die komplette Riesendatei in den RAM des Servers geladen - eine Katastrophe.

Wenn schon, dann mußt Du alle(!) Funktionen auskommentieren, die mit "ob_" anfangen und am allerwichtigsten die Funktion ob_start().

spacewalker wrote:Im Grund möchte ich erreichen, dass der Benutzer auf eine Link klickt, z.b: http://server/login1.php?file=1000.iso, dann nach einem Passwort gefragt wird und dann die Datei runtergeladen wird.


Dafür benötigt man überhaupt kein PHP, speichere und verlinke die Datei einfach in ein Verzeichnis, welches einen (Apache)-Passwortschutz hat.
Nobbie
 
Posts: 13183
Joined: 09. March 2008 13:04


Return to PHP

Who is online

Users browsing this forum: No registered users and 12 guests