Download einer Datei funktioniert nicht

Status
Dieses Thema wurde gelöst! Zur Lösung gehen…

tklustig

Erfahrenes Mitglied
Hallo Leute,
folgender an sich simpler Code soll eine jeweilige Datei downloaden. Das funktioniert soweit auch, allerdings kann ich die Datei nicht entpacken; sie ist beschädigt(Das Original hingegen ist unbeschädigt). Weiß jemand Rat?
PHP:
<!Doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Upload</title>
    </head>
    <body>
        <?php
        $filename1 = "Programmierung.zip";
        $filename2 = "VBA_for_Excel.zip";
        $dir = getcwd() . "/";
        $type = 'application/zip';
        ?>
        <form action="download.php" name="formular" id="formular" method="post" >
            <p>Downloadbuttons:</p>
            <input type=submit name="download1" id="betreff" value="<?php echo $filename1 . " Downloaden"; ?>"><br>
            <input type=submit name="download2" id="betreff" value="<?php echo $filename2 . " Downloaden"; ?>"><br>
        </form>
        <?php
        if (!empty($_REQUEST["download1"])) {
            if (file_exists($dir . $filename1)) {
                makeDownload($filename1, $dir, $type);
            } else {
                echo"<h3>Datei nicht existent</h3>";
            }
        }
        if (!empty($_REQUEST["download2"])) {
            if (file_exists($dir . $filename2)) {
                makeDownload($filename2, $dir, $type);
            } else {
                echo"<h3>Datei nicht existent</h3>";
            }
        }
        ?>
    </body>
</html>
<?php

function makeDownload($file, $dir, $type) {
    header("Content-Type: $type");
    header("Content-Disposition: attachment; filename=\"$file\"");
    //readfile($dir . $file);
}
?>
 
Zuletzt bearbeitet:
Das funktioniert soweit auch, allerdings kann ich die Datei nicht entpacken; sie ist beschädigt(Das Original hingegen ist unbeschädigt). Weiß jemand Rat?
Das ist tatsächlich komisch:
http://php.net/manual/de/function.header.php
Beachten Sie, dass Sie die Funktion header() aufrufen müssen, bevor Sie irgendeine andere Art von Ausgabe (seien es normale HTML-Tags, Leerzeilen in einer Datei oder von PHP) zum Client schicken. Es handelt sich hier um einen typischen Fehler, der zum Beispiel auftritt, wenn Sie Code mittels includeoder require oder einer anderen Dateizugriffs-Funktion einlesen, die Leerzeichen oder Leerzeilen enthalten, die ausgegeben werden, bevor header() aufgerufen wird. Das gleiche Problem kann auch auftreten, wenn Sie eine Datei verwenden, in der HTML und PHP vermischt wurden.

Dein Code sollte so eigentlich gar nichts machen. Aber öffne deine zip-Dateien mal in einem Texteditor (oder meinetwegen mit einem Hexeditor). Ich nehme auch an, dass die Dateigrössen überhaupt nicht übereinstimmen.

Ein Diff der Dateien könnte auch interessant sein. Falls möglich, kannst du die Dateien ja auch hier anhängen, dann schaue ich sie mir an.

/EDIT: Oh, du hast ja sogar das readfile() auskommentiert. Absicht? So können deine Dateien ja gar nicht identisch sein

Gruss
cwriter
 
Yuup. Das ist seltsam. Wenn ich folgenden Code ausführe, funktioniert sowohl der Download, als auch das Entpacken:
PHP:
<?php
$file = "VBA_for_Excel.zip";
if (!file_exists($file))
    die("File not found");
header("Content-Disposition: attachment; filename=\"$file\"");
header("Content-Length: " . filesize($file));
header("Content-Type: application/octet-stream;");
readfile($file);
?>
Wenn ich diesen Code ausführe, klappt der Download, allerdings ist die Datei immer noch beschädigt. Die Dateigröße stimmt allerdings. Ich kann die header-Funktion doch erst dann aufrufen, wenn auf einer der beiden Buttons gedrückt wurde. Vorher macht das doch gar keinen Sinn. Muss ich also den Ansatz völlig verändern?
PHP:
<!Doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Upload</title>
    </head>
    <body>
        <?php
        $filename1 = "Programmierung.zip";
        $filename2 = "VBA_for_Excel.zip";
        $dir = getcwd() . "/";
        ?>
        <form action="download.php" name="formular" id="formular" method="post" >
            <p>Downloadbuttons:</p>
            <input type=submit name="download1" id="betreff" value="<?php echo $filename1 . " Downloaden"; ?>"><br>
            <input type=submit name="download2" id="betreff" value="<?php echo $filename2 . " Downloaden"; ?>"><br>
        </form>
        <?php
        if (!empty($_REQUEST["download1"])) {
            if (file_exists($dir . $filename1)) {
                makeDownload($filename1);
            } else {
                echo"<h3>Datei nicht existent</h3>";
            }
        }
        if (!empty($_REQUEST["download2"])) {
            if (file_exists($dir . $filename2)) {
                makeDownload($filename2);
            } else {
                echo"<h3>Datei nicht existent</h3>";
            }
        }
        ?>
    </body>
</html>
<?php
function makeDownload($file) {
    header("Content-Disposition: attachment; filename=\"$file\"");
    header("Content-Length: " . filesize($file));
    header("Content-Type: application/octet-stream;");
    readfile($file);
}
?>
 
Zuletzt bearbeitet:
Wo ist denn jetzt der Unterschied??
Naja, im ersten Beispiel gibst du vor "header()" nichts aus, im 2. steht der HTML-Code aber vor dem header(). (header() leitet nicht automatisch einen neuen Kontext ein).

Ich kann mir gut vorstellen, dass der Browser die Header zwar liest, aber den schon übertragenen HTML-Code vorne ranhängt. Wie gesagt: Schau dir die beschädigte Datei im Texteditor (Notepad++) oder Hexeditor an. Das hilft oft bei solchen Dingen.

(Hypothese: Da steht der HTML-Code vorne dran; das sollte leicht erkennbar sein)

Gruss
cwriter
 
Ich kann die header-Funktion doch erst dann aufrufen, wenn auf einen der beiden Buttons gedrückt wurde. Vorher macht das doch gar keinen Sinn. Muss ich also den Ansatz völlig verändern?
Die zip-Datei sieht nach dem Runterladen völlig anders aus, als das Original, nämlich so:
Code:
<!Doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Upload</title>
    </head>
    <body>
                <form action="download.php" name="formular" id="formular" method="post" >
            <p>Downloadbuttons:</p>
            <input type=submit name="download1" id="betreff" value="Programmierung.zip Downloaden"><br>
            <input type=submit name="download2" id="betreff" value="VBA_for_Excel.zip Downloaden"><br>
        </form>
        PK    ëcÛHJì(zŽ3  >     Arrays&For_Each.xlsmí»W\kÖ5ZP¸»»»»;ÁÝ    îîàÁ‚»[pww    nÁÝ]oúí÷ÞÓïôý_ϵk×Øõ¬ªQsÙ3ö\Š2@04
  6QÖ-¼@  p   ª#joçbj碯êá`êü™ÁÝÖ†(”*
ø/þ¯Æ¸ªŽB/šç• 7»5ª1\ ä€äˆ¯Ð"¾f¡uzVÀåÿªŸX¯x^xçé‚wŠó¢F’T2’"oz-ÃE
X…Spc]d‡\Öœg²Abcì ÖðN,<ä¢ÆÛÈ
"¨1µ–E⃬…&|ͣƅÅ57>N¯OÖ½tß    "oñh
.
.
Der zieht also den Html-Code in die zip rein und beschädigt damit deren Inhalt....
 
Der zieht also den html-Code in die zip rein und beschädigt damit deren Inhalt....
*Auf meine Schulter klopf*

Ich kann die header-Funktion doch erst dann aufrufen, wenn auf einer der beiden Buttons gedrückt wurde. Vorher macht das doch gar keinen Sinn. Muss ich also den Ansatz völlig verändern?
Naja.

PHP:
<?php
        // Prüfe ERST, ob das Formular schon gesendet wurde (= Ein Knopf gedrückt wurde)
        if (!empty($_REQUEST["download1"])) {
            if (file_exists($dir . $filename1)) {
                makeDownload($filename1);
                return; // Hör auf, auszugeben
            } else {
                echo"<h3>Datei nicht existent</h3>";
            }
        }
        if (!empty($_REQUEST["download2"])) {
            if (file_exists($dir . $filename2)) {
                makeDownload($filename2);
                return; // Hör auf, auszugeben
            } else {
                echo"<h3>Datei nicht existent</h3>";
            }
        }
        ?>
<!Doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Upload</title>
    </head>
    <body>
        <?php
        $filename1 = "Programmierung.zip";
        $filename2 = "VBA_for_Excel.zip";
        $dir = getcwd() . "/";
        ?>
        <form action="download.php" name="formular" id="formular" method="post" >
            <p>Downloadbuttons:</p>
            <input type=submit name="download1" id="betreff" value="<?php echo $filename1 . " Downloaden"; ?>"><br>
            <input type=submit name="download2" id="betreff" value="<?php echo $filename2 . " Downloaden"; ?>"><br>
        </form>
        
    </body>
</html>
<?php
function makeDownload($file) {
    header("Content-Disposition: attachment; filename=\"$file\"");
    header("Content-Length: " . filesize($file));
    header("Content-Type: application/octet-stream;");
    readfile($file);
}
?>
So müsste es eigentlich gehen.

Allerdings ist dieser (php-only)-Ansatz etwas angestaubt. Es funktioniert, aber da du mit dem form ja die Seite neu lädst, kannst du weniger auf der Seite machen als mit neueren Methoden wie XHR / ajax / Konsorten. Der PHP-Ansatz hat aber für sich, dass es kein JS braucht.

Gruss
cwriter

Gruss
cwriter
 
Ur the Greatest! Geradezu unheimlich, wie du dem Problem auf die Spur gekommen bisto_O Jetzt funktioniert der ganze Krempel auch ohne JS. Ich für meinen Teil werde mir merken, dass die Reihenfolge der Codeausführung immer dann eine Rolle spielt, wenn header()-Funktionen ins Spiel kommen. Danke für deine Unterstützung....
 
Status
Dieses Thema wurde gelöst! Zur Lösung gehen…
Zurück