Dateidownload über PHP-Script funktioniert nicht - Headerproblem

TMM

Mitglied
Hallo liebe PHP-Cracks,
ich wollte auf meiner Seite die Downloadlinks vom direkten Link in einen PHP-Aufruf mittels ID ummodeln. Ich habe mir dazu auch die verschiedenen Posts hier im Forum und hier
http://www.php-faq.de/q/q-datei-download.html angeschaut und einigermaßen befolgt, leider gibt es beim Aufruf der einzelnen Downloads ernste Probleme, mit anderen Worten Firefox hängt sich auf und spuckt ca. 100.000 Zeichen auf der aufgerufenen Seite aus, vorher gibt es aber noch folgende Meldungen:

Warning: filesize() [function.filesize]: stat failed for .../downloads/beispiel.zip in .../html/NEUES_PROJEKT/download.php on line 13

Warning: Cannot modify header information - headers already sent by (output started at .../html/NEUES_PROJEKT/download.php:13) in .../html/NEUES_PROJEKT/download.php on line 13

Warning: Cannot modify header information - headers already sent by (output started at .../html/NEUES_PROJEKT/download.php:13) in .../html/NEUES_PROJEKT/download.php on line 14


Hier der zugehörige Code:

PHP:
<?php  
  
    include_once('php/db_login.php');
  
  
    $_GET["id"];
    
          $result = mysql_query('SELECT dl_link FROM downloads WHERE dl_ID = "' . mysql_real_escape_string($_GET['id']) . '"');
          $filename = mysql_result($result,0,0); 
          
          header("Content-Disposition: filename=\"$filename\"");  
          header("Content-Length: ".filesize($filename)); 
          header("Content-Type: application/octet-stream"); 

          readfile($filename);     
      
            
?>

Die Abfrage scheint soweit in Ordnung, zumindest liest er den Link zum Download aus der Datenbank aus, das Problem sind die Header. Der Code ist die komplette Datei, es wird kein Template o.ä. mit Headern inkludiert, deshalb frage ich mal nach, wie die Lösung aussehen muss.
Bei der Gelegenheit auch gleich die Frage, ist dieses Skript ausreichend gegen Injections geschützt?

Danke für Eure Hilfe!
 
Zuletzt bearbeitet:
Dateidownload über PHP-Script funkt ...

Moin,

kenne den fehler "cannot modify header..." egtl nur wenn man versucht den header zu verändern nachdem er bereits gesetzt ist. Da kann schon ein leerzeichen vor dem <?php für verantwortlich sein. Pruef mal ab, ob bei deinem code keinerlei ausgabe gemacht wird bis zu deinem gesetzten header. Leerzeichen und -zeilen zwischen den php tags sind wurscht.

Vlt bringt dich das ein stück weiter.
 
habe es nochmal überprüft, vor dem <?php kommen keine Zeichen, auch habe ich mal mit der Funktion headers_sent() überprüft, ob vor dem Versenden der header bereits ein anderer header übermittelt wird, die Ausgabe der php-Datei ist leer, allerdings gibt der Validator einen Fehler aus:
Cause:

xml prolog at the beginning of the document was not closed, or the file is empty.
Example:
Good

<?xml version="1.0" encoding="UTF-8"?>
Good

<?xml version="1.0" encoding="UTF-8"
Solution:

Make sure you have closed the prolog. Kann es vielleicht daran liegen?
Auch habe ich mir überlegt, ob es vielleicht der falsche Header Type ist, der übermittelt wird, downgeloaded werden sollen ausschließlich ZIP...

Danke für eure weitere Hilfe.
 
Habe den Fehler gefunden, das Problem war die Mehrfachnennung der Header, auch wenn dies in allen Foren so vorgeschlagen wird...Habe nun ein funtkionierendes Script, das folgendermaßen ausschaut:

PHP:
<?php

include_once('php/db_login.php');
  
  
    $_GET['id'];  
    $id = $_GET['id']; 
    $id = (int)$id;
    
    // Prüfen, ob $id ein Integer ist   
    if ($id > 0)
        {
          $result = mysql_query('SELECT dl_filename, dl_link FROM downloads WHERE dl_ID =' . $id);
          $filename = mysql_result($result,0,0); // Dateiname aus der DB holen
          $link = mysql_result($result,0,1); // Downloadlink aus der DB holen
              
         
          header("Content-Disposition: attachment; filename=\"$filename\""); 
                ("Content-Length: ".filesize($filename)); 
                ("Content-Type: x-type/subtype");    

              
                   
          readfile($link); // Ausgabe 
          
          //DOWNLOAD-Zähler um eins erhöhen
          mysql_query('UPDATE downloads SET dl_count = dl_count+1 WHERE dl_ID =' . $id);
                     
        }

    // Ausführen, wenn $id kein Integer ist
    else 
        
        die("The requested download-ID wasn´t found in database.");
        
          
?>

Das Skript funktioniert soweit in allen mir zur Verfügung stehenden Browsern, ein kleines Problem besteht aber noch, die Dateigröße wird nicht übermittelt, kann mir da jemand eine Lösung sagen?

Ansonsten danke an alle, die hier geholfen haben ;)
 
Ich glaube der Fehler liegt darin, dass du bei den zwei Zeilen kein header() davor geschrieben hast:
PHP:
header("Content-Disposition: attachment; filename=\"$filename\"");  
                ("Content-Length: ".filesize($filename));  
                ("Content-Type: x-type/subtype");

Was wahrscheinlich dazu führt, dass header() nicht ausgeführt wird. Zumindest habe ich diese Schreibweise noch nie gesehen.
 
Wie bereits gesagt, ich hatte bei den zwei Zeilen Header davorstehen, da wurde das Skript abgebrochen mit dem Hinweis, dass in Zeile 13 (Content-Disposition) bereits ein Header gesendet wurde und deshalb die Zeilen 14 und 15 keinen Header senden konnten.
So wie die Script oben steht funktioniert es bis auf das Senden der Dateigröße (gestestet mit Firefox 3.6.13 und IE 8.0)...
Content-Disposition wird ausgeführt und den Dateityp erkennen die Browser auch, was ja m.W. vor allem bei Firefox ein Problem darstellt...
Dass die Dateigröße nicht gesendet wird ist zwar nicht hübsch, allerdings werden auf der Seite die Dateigrößen vor dem DL auch nochmal angegeben...
 
Zurück