2017-03-01 1 views
3

Ich erstelle derzeit eine Funktion, die Dateien von Remote-Server herunterladen würde. Mein Skript funktioniert gut für alle Dateitypen, aber es funktioniert nicht für die msg-Dateien aus irgendeinem Grund (Es lädt leere Datei (0K)). Gleiches Verhalten in Chrome und IE übrigens. Ich dachte, das Problem ist mit der Dateigröße, so habe ich getestet, um große Zip-Datei herunterladen und es funktioniert auch gut, scheint, dass nur msg-Dateien, die ich habe, Problem mit.Wie msg-Datei mit PHP herunterladen

Mein Skript:

Was mache ich falsch?

P.S. Ich denke, mögliche Lösung ist zu archivieren (zip) MSG-Datei während des Hochladens und dann herunterladen Sie es als. ZIP statt, aber ich bin auf der Suche nach einer besseren Lösung.

+0

keine Antwort, sondern ein Vorschlag für Ihren Skript: Sie sollten sanieren Ihre '$ _GET [ 'file_name']', jemanden zu vermeiden Sachen vorbei wie '../ passwd' –

+2

Sie können die MSG-Datei vom Remote-Server von dem Server herunterladen, auf dem Ihr PHP-Skript mit anderen Mitteln als PHP läuft, z. mit 'wget http: // mypath/uploads/test.msg'? Ich habe dein Skript mit einer lokalen Datei getestet, z. '$ file_url = 'test.msg';', und das funktioniert hier, also vermute ich ein Problem, das vom Remote-Server kommt. Sie könnten auch den Rückgabewert von 'readfile' überprüfen - wenn es' false' ist, gibt es einen Fehler beim Lesen der Datei. –

+0

Ich habe das Skript getestet, es lädt Remote 'msg' Datei. nginx + php 5.6. Sind Sie sicher, dass das Skript Zugriff auf die Datei hat? Was, wenn es der Server in 'mypath' ist, der' .msg' Dateien nicht gibt? –

Antwort

3

my comment in einer Antwort Erweiterung:

ich das Skript mit einer lokalen Datei getestet, zum Beispiel. $file_url = 'test.msg';, und das funktioniert hier. Daher vermute ich, dass ein Problem beim Abrufen der Datei vom Remote-Server vorliegt. Können Sie die Remote-MSG-Datei von dem Server herunterladen, auf dem Ihr PHP-Skript mit anderen Mitteln als PHP läuft, z. mit wget http://mypath/uploads/test.msg? Sie können auch den Rückgabewert von readfile - 10 überprüfen. Wenn Sie die Datei nicht herunterladen können oder readfile den Wert false zurückgibt, liegt das Problem nicht in Ihrem Code, sondern in einer Serverkonfiguration oder einem Verbindungsproblem, das Sie zuerst beheben müssen.

In Bezug auf Ihren Code: Sie sollten Ihre $_GET['file_name'] sterilisieren, um jemanden zu vermeiden passieren Zeug wie ../passwd.

2

Probieren Sie einen anderen Inhaltstyp verwenden:

header("Content-Type: application/download"); 
+0

Ich habe gerade versucht, einen anderen Header zu verwenden, aber immer noch keine Freude, dasselbe Problem! –

+0

@DenissMuntjans aktualisiert versuchen Sie diese :) – EL3PHANTEN

+0

Immer noch das gleiche, es lädt leere msg-Datei! –

3

Sie versuchen readfile mit einer URL-Speicherort der Datei zu verwenden, die nur möglich ist, wenn fopen wrappers aktiviert wurden.

Von PHP readfile:

Tip Eine URL kann mit dieser Funktion als Dateinamen verwendet werden, wenn die fopen wrappers aktiviert wurden. Weitere Informationen dazu, wie Sie den Dateinamen angeben, finden Sie unter fopen(). Siehe Supported Protocols and Wrappers für Links zu Informationen darüber, welche Fähigkeiten die verschiedenen Wrapper haben, Hinweise zu ihrer Verwendung und Informationen über alle vordefinierten Variablen, die sie bieten können.

Es ist nicht sicher, und Sie sollten eine lokale Systempfad insted einer URL wie folgt verwenden:

// Get parameter form html page 
if(isset($_GET['file_name'])) $file_name = $_GET['file_name']; 

$file_name = str_replace('"', '\\"', $file_name); 
//$file_url = 'http://mypath/uploads/' . $file_name; 
// The script is located to one level up directory of the uploads directory 
// You can change this to fit your script and uploads directory locations 
$uploads_local_path = __DIR__.'/uploads/'; 
$file_path = $uploads_local_path.$file_name; 

header('Content-Type: application/octet-stream'); 
header("Content-disposition: attachment; filename=\"".$file_name."\""); 
header("Content-Transfer-Encoding: Binary"); 

readfile($file_path); 
exit; 

und jetzt funktioniert es und lädt die Datei. Passen Sie einfach auf und haben Sie die richtigen Pfadpositionen für das Verzeichnis uploads.

Sie können sogar mein lokales Beispiel basierend auf Ihren Code hier versuchen, eine Datei herunterladen: http://zikro.gr/dbg/php/dl-file/

Ein direkter Link zur Download-Skript können Sie versuchen: http://zikro.gr/dbg/php/dl-file/dodl.php?file_name=1011191_orig.png

1

Versuchen Sie, einen User-Agent hinzuzufügen und alle MIME-Typen auf Ihre Anfrage zu akzeptieren.von cURL:

// Get parameter form html page 
if(isset($_GET['file_name'])) $file_name = $_GET['file_name']; 

$file_name = str_replace('"', '\\"', $file_name); 
$file_url = 'http://mypath/uploads/' . $file_name; 

header('Content-Type: application/octet-stream'); 
header("Content-disposition: attachment; filename=\"".$file_name."\""); 
header("Content-Transfer-Encoding: Binary"); 

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, $file_url); 
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0'); 
$headerData[] = 'Accept: */*'; 
curl_setopt($ch, CURLOPT_HTTPHEADER, $headerData); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
$data = curl_exec ($ch); 
$error = curl_error($ch); 
curl_close($ch); 
echo $data; 
exit; 
1

Probieren Sie es

// Get parameter form html page 
if(isset($_GET['file_name'])) $file_name = $_GET['file_name']; 

$file_name = str_replace('"', '\\"', $file_name); 
$file_url = 'http://mypath/uploads/' . $file_name; 

header("Content-Type: application/download"); 
header("Content-disposition: attachment; filename=\"".$file_name."\""); 
header("Content-Transfer-Encoding: Binary"); 

readfile($file_url); 
exit; 
0

Ich denke, Sie müssen die Content-Länge-Header angeben, und ich denke, deaktivieren Caching kann auch helfen.

zum Beispiel:

header("Content-length: " . strlen($output); // tells file size 
header("Pragma: no-cache"); 
header("Expires: 0");