
jimmyjambles
Ich versuche, ein Problem zu beheben, das ich beim Herunterladen einer “zip”-Datei aus einem PHP-Skript habe. Es scheint, dass, wenn ich die Datei mit dem folgenden Code herunterlade, die heruntergeladene Datei ein zusätzliches 0A09 an den Anfang der Datei angehängt hat, was dazu führt, dass Winzip einen Korruptionsfehler ausgibt.
<?php
$pagePermissions = 7;
require_once ('util/check.php');
require_once ('util/file_manager.php');
$file_manager = new FileManager();
if ($_SERVER['REQUEST_METHOD'] == "GET") {
if (isset($_GET['q']) && $_GET['q'] == 'logout') {
//require_once ('util/users.php');
//$userdata = new Userdata();
$userdata -> kill_session();
header("Location: download.php");
exit ;
}
if (isset($_GET['q']) && $_GET['q'] == 'fetch') {
if (isset($_GET['name'])) {
@apache_setenv('no-gzip', 1);
header("Content-length: " . filesize('upload/' . $_GET['name']));
header('Content-type: application/zip');
//header("Content-Disposition: attachment; filename=\"{$_GET['name']}\" ");
header("Content-Disposition: attachment; filename={$_GET['name']}");
header('Content-Transfer-Encoding: binary');
readfile('upload/' . $_GET['name']);
exit();
}
}
}
?>
Jede Hilfe wäre sehr willkommen, die Datei lädt problemlos über einen direkten Link herunter, die an den Anfang der Datei angehängten 2 Bytes treten nur durch diesen Code auf. Danke im Voraus

Yanik Rochon
Entfernen Sie das letzte ?>
und überprüfen Sie, ob sich Ihr Eröffnungs-Tag in der allerersten Zeile befindet, beim allerersten Zeichen Ihrer Skripte. PHP-Dateien unterlassen Sie müssen mit End-Tags enden. Der Grund, warum Ihre heruntergeladenen Dateien ein (oder mehr) \r\n
liegt daran, dass PHP alles außerhalb von direkt echoen (ausgeben) wird <?php ?>
. Wenn Ihr Skript HTML nicht wiedergibt, lassen Sie normalerweise das schließende PHP-Tag weg, da es nicht obligatorisch ist und meiner Meinung nach mehr Probleme verursacht als alles andere.
** Bearbeiten **
Wenn Sie das PHP-Handbuch für readfile
Sie haben ein nützliches Beispiel, so ziemlich den Code, den Sie in Ihrer Frage haben, weniger zwei Codezeilen:
@apache_setenv('no-gzip', 1);
header("Content-length: " . filesize('upload/' . $_GET['name']));
header('Content-type: application/zip');
//header("Content-Disposition: attachment; filename=\"{$_GET['name']}\" ");
header("Content-Disposition: attachment; filename={$_GET['name']}");
header('Content-Transfer-Encoding: binary');
// add these two lines
ob_clean(); // discard any data in the output buffer (if possible)
flush(); // flush headers (if possible)
readfile('upload/' . $_GET['name']);
exit();
Wenn Sie danach immer noch ein Problem haben, liegt das Problem möglicherweise nicht an Ihrem PHP-Code.

Raffiniert
Entschuldige die späte Antwort…..
Ich weiß nicht, ob ich Recht habe, bis Sie hier abstimmen. . . .
Bearbeiten Sie Ihren Code wie folgt:
ob_start("");
//instead of ob_start(); with out a null callback
und
ob_end_clean(); //at the end , Note : "important" add instead of ob_end_flush()
dh;
ob_start("");
//header
ob_end_clean();
Ich bin heute auf ein ähnliches Problem im Zusammenhang mit readfile() gestoßen. Es stellt sich heraus, dass in meiner php.ini-Datei die Ausgabekomprimierung aktiviert ist und das das Flash-Modul beim Versuch, die Datei abzurufen, durcheinander gebracht hat. (Ich denke, es konnte nicht damit umgehen.)
Alles, was ich tun musste, war die Komprimierung in der Datei php.ini auszuschalten:
zlib.output_compression = off
Oder alternativ in Ihrem Skript:
<?php ini_set('zlib.output_compression', 'Off'); ?>
Ich möchte dies nur teilen, falls jemand anderes Probleme hatte, Dateien von einer readfile() -Ausgabe zu empfangen.
Ich hatte ein ähnliches Problem in Joomla (2.5), bei dem ich readfile verwendete, um Excel-Dateien (.xls) an den Benutzer zurückzugeben.
Ich habe auch bemerkt, dass die Text- und XML-Dateien am Anfang auch etwas Code eingefügt hatten, aber ich habe es fast ignoriert, weil XML- und Text-Reader dazu neigten, die Dateien immer noch zu öffnen.
Ich habe mich entschieden, Yanicks Vorschläge auszuprobieren (anstatt mit Serverkomprimierungsoptionen zu spielen), indem ich einfach den Puffer vor der Readfile geleert habe:
ob_clean(); // discard any data in the output buffer (if possible)
flush(); // flush headers (if possible)
Puh, es hat funktioniert. Ich schlage dies als alternative Antwort vor: Um die Grundursache hervorzuheben, zu zeigen, dass es ein Joomla-Problem beheben kann, und weil ich eine Mischung aus Binär- und Textrückgaben hatte.
Nur um hinzuzufügen (Entschuldigung, wenn dies offensichtlich ist!) – die Mime-Typ-Einstellung hat gut funktioniert:
$document = JFactory::getDocument();
$document->setMimeEncoding($mimetype);
Ich musste nicht einmal „Content-Transfer-Encoding: binary“ einstellen, wenn der Mime-Typ „application/octet-stream“ war.
Ich hatte das gleiche Problem, also habe ich diese Header verwendet und meine Lösung bekommen.
$filename = ABSPATH.'/wp-content/summary/user_content/'.trim($file);
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Description: File Transfer');
header('Content-Type: text/text');
header('Content-Disposition: attachment; filename="'.$file.'"');
header('Content-Transfer-Encoding: binary');
header('Cache-Control: max-age=0');
readfile($filename);
exit;

Michael Chaplin
Ich hatte ein ähnliches Problem mit Leerzeichen am Anfang einer Bilddatei.
Ich vermute, dass mein Problem durch Leerzeichen vor dem Öffnen verursacht wurde
Was für mich funktionierte, war:
@ob_start(''); //@ supresses a warning
//header entries
ob_end_clean();
ob_clean();
readfile($file);
10150300cookie-checkPHP readfile() fügt der heruntergeladenen Datei zusätzliche Bytes hinzuyes
Ich hoffe, Sie verwenden das nicht in einer Produktionsumgebung, es ermöglicht einem Besucher das Abrufen irgendein Datei auf Ihrem Server, auf die PHP Zugriff hat.
– igorw
7. November 2011 um 19:40 Uhr
Hat nichts mit Ihrem Fehler zu tun, aber … filtern Sie Ihre Eingabe! Andernfalls kann ich ?name=../../../etc/passwd in der URL angeben.
– Alex Howansky
7. November 2011 um 19:41 Uhr
readfile()
wird die Anzahl der aus der Datei gelesenen Bytes am Ende anhängen.– Satvik
30. Juni 2021 um 13:27 Uhr