mit readfile() ausgegebenes Bild wird als leere 0KB-Datei heruntergeladen

J

j-l-n

Guest
Folgendes Skript lädt die angegebene Bilddatei herunter:
PHP:
    header("Content-Type: application/octet-stream");
    header("Content-Disposition: attachment; filename=\"$filename\"");
    header("Content-Length:\"$size\"");
    header("Pragma: no-cache");
    header("Expires: 0");
    readfile($path);

$path ist ein gültiger Pfad, das Bild ist vorhanden. $size ist auch richtig berechnet; ebenso enthält $filename den richtigen Inhalt.
Dennoch lädt der Browser nur eine 0KB-Datei herunter. Warum?
 
Ich würde mal zwei Sachen überprüfen:
- Darf PHP bzw. der Apache auch auf die Datei zugreifen?
- Steht was im Error-Log?

Eventuell auch mal ein if(file_exists($file)) drum rum, um sicher zu gehen das die Datei existiert.
 
Ich würde mal zwei Sachen überprüfen:
- Darf PHP bzw. der Apache auch auf die Datei zugreifen?
- Steht was im Error-Log?
Nein, da steht nix drinn.

Eventuell auch mal ein if(file_exists($file)) drum rum, um sicher zu gehen das die Datei existiert.
Ja, ich hab bereits ein
PHP:
if(is_readable($file)){
herumgesetzt; und wie gesagt existiert die Datei und ich hab auch schon mit echo überprüft, ob in den Variablen das richtige drinsteht...
 
Am Ende des Headers wird eine Leerzeile benötigt, um ihn vom Content zu trennen. Macht dein Code das? Ich bin mir bei diesen PHP Kommandos nicht sicher. Außerdem muss ein Bild binär geöffnet und zum Browser gesendet werden, macht readfile() das automatisch oder nur mit Parametern?
 
Ein ein gültiger Pfad für Path reicht nicht, readfile benötigt einen Dateinamen (u.U. mit kompletten Pfad). Vermute hier liegt der Fehler.
 
Stimmt, jspit hat Recht, die Variable $filename im readfile() fehlt. Julian, versuch mal readfile("$path/$filename");
 
Noch zwei Anmerkungen:
- Variablen in Strings gepackt wie "$var" gelten in PHP als uncool, auch wenn es noch in vielen (älteren) Tuturials so gezeigt wird. Besser ist eine Verkettung mittels dot (.)
- Das Escapen von Double Quotes erspart man sich häufig bei Nutzung von Single Quotes

Beispiele:
PHP:
header('Content-Disposition: attachment; filename="' . $filename . '"');

readfile($path . DIRECTORY_SEPARATOR . $filename);

Die Konstante DIRECTORY_SEPARATOR ist unter Linux ein / und für Win-Systeme ein \
 
$path ist vielleicht ein etwas missverständlicher Variablenname. Und zwar enthält er sowohl Pfad als auch Bild. (Bsp.: "uploads/Bild1.jpg").
 
Wenn $path auf eine reale Bilddatei zeigt, ist sowas wie
PHP:
if(is_readable($file)){
sinnfrei.
Aktiviere mal das error_reporting, ob da was kommt.
Harte Fehler kann ich im obgen Scriptschnipsel nicht erkennen.
 
Wenn $path auf eine reale Bilddatei zeigt, ist sowas wie
PHP:
if(is_readable($file)){
sinnfrei.
Nein, ist es nicht. Denn es prüft, ob die Datei wirklich existiert (für fertige Version gedacht).

Aktiviere mal das error_reporting, ob da was kommt.
Harte Fehler kann ich im obgen Scriptschnipsel nicht erkennen.
Wenn ich die Dateigröße mittels
PHP:
filesize($path);
ausgebe, wird sie korrekt angezeigt. Auch wenn ich nur mittels readfile() das Bild auslese, werden viele Zeichen dargestellt. Aber wenn ich das Ganze dann durch die Angabe des headers zum Download bringe, lädt der Browser nur eine 0,00B große Datei herunter.
 
Kannst du mal zwei Testlinks machen? Einen mit und einen ohne die header() aufrufe.

@mikdoe: header ist in PHP die erste Wahl, um HTTP-Header auszugeben. Erzeugt automatisch die Leerzeilen und gibt eine Warnung aus, wenn die Header nicht mehr gesendet werden können.
 
Und das header() setzt die Leerzeile zur Abtrennung des Content automatisch? Auch bei mehreren untereinander?
 
Hm... im HTTP-Header steht bei Content-Length definitiv eine Null drin... zeig' doch mal den kompletten Code für alle drei Varianten.

EDIT: Moment... mach' mal die Anführungsstriche im Content-Length weg.
 
Was dem Korbinian manchmal auffällt ist schon faszinierend. Hab bei mir mal nachgesehen, hab es auch überall ohne Anführungszeichen aber hier wäre mir das wahrscheinlich niemals aufgefallen. Manches macht man halt nicht oft genug oder hat Module für solche Sachen.
 
Zurück
Oben