PHP readfile von ftp server

raumgleita

Cadet 4th Year
Registriert
Feb. 2008
Beiträge
119
Hallo

Ich nutze die funktion "readfile" so wie in der Dokumentation (http://php.net/manual/en/function.readfile.php).

PHP:
 header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.basename($file));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    ob_clean();
    flush();
    readfile($file);
    exit;

Der Download funktioniert für kleinere Dateien (so 600MB). Grosse Image-Dateien (dmg/iso) ab 2GB sind nach dem Download korrupt. Also ich kann die Image Dateien nicht mehr mounten.
Der Download erfolgt über ftp von einem NAS. Problem besteht bei verschiedenen Browsern.


An was könnte das liegen?

Besten Dank!
raumgleita
 
Hm.. Hab ich mir auch schon gedacht. Ich muss mir das ganze morgen nochmals genauer anschauen. Wenn ich ein 2,1 GB grosse Datei herunterlade, ist sie manchmal nur 1.9GB gross aber manchmal 2,1GB gross oder dazwischen. Vielleicht gibt es wirklich ein timeout und bricht nach einer gewissen Zeit ab... Ich berichte morgen von meine neue Erkenntnisse. Besten Dank schon mal!
 
Es gibt schon einen Timeout, wie lange PHP wartet, bzw. Daten liefert. Mach doch mal ein phpinfo() und schau dir die Limits an (es gibt verschiedene). ;)

Wenn du Daten lieferst, würde ich es aber eher mit fopen und while umsetzen - das belastet den Server nicht so stark wie readfile. Ich hab eine Funktion dafür:

PHP:
function sendFileToBrowser($filelocation = NULL, $filename = NULL, $org_filename = '', $ctype = 'application/octet-stream', $download = FALSE){
/**
 * Verschickt eine Datei zur Ansicht oder Download an den Browser
 *
 * @project		-
 * @author		Boris Bojic <bojic@devshack.biz>
 * @copyright	Copyright (c) 2010, Boris Bojic (DevShack)
 * @version		Tue, 06 Jul 2010 13:19:17 +0200
 *
 */

	// Kein Originalname übergeben? Dann nehmen wir den Dateinamen
	if($org_filename == ''){
		$org_filename = $filename;
	}

	// Soll die Datei zum Download angeboten werden?
	if($download === TRUE){
		header('Pragma: public');
		header('Expires: 0');
		header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
		header('Content-Transfer-Encoding: binary');
		header('Content-Disposition: attachment; filename=' . $org_filename . ';');	
	}

	header('Content-Type: ' . $ctype);
	header('Content-Length: ' . filesize($filelocation . $filename));
	//	readfile($filelocation . $filename);

	$file = fopen($filelocation . $filename, "r");

	while(!feof($file) and (connection_status()==0)) {
		print(fread($file, 1024*8));
		flush();
	}
	
	fclose($file);
	
	die();
	
}
 
Zuletzt bearbeitet:
ich würd sagen, readfile haut dir den speicher voll, sicher dass du alle fehlermeldungen anzeigen lässt?
 
Ok. Ich glaube ich weiss nun was das Problem sein könnte. Er zeigt alle Files grösser als 2GB als genau 2GB an (Ist mir zuerst nicht aufgefallen da ich die Ausgabe in Bytes habe). Scheint ein sehr bekanntes Problem zu sein:
Note: Because PHP's integer type is signed and many platforms use 32bit integers, filesize() may return unexpected results for files which are larger than 2GB. For files between 2GB and 4GB in size this can usually be overcome by using sprintf("%u", filesize($file)).
http://php.net/manual/en/function.filesize.php

Ich habe ein paar Beispiele von den Comments ausprobiert doch ohne Erfolgt. Anscheinend ist auf Windows die Lösung mit einer inoffiziellen 64 bit php Version. Ich benutze lampp auf Ubuntu.

Jemand schon mal das gleiche Problem gehabt?
 
wie wäre es denn wenn du als workaround die datei in kleinere teile spaltest, oder ist die zielgruppe dafür nicht erfahren genug?

ansonsten vl ne andere technik einsetzen, flex z.b. das kann streamen.
 
lol. Nein für die User ist das nichts. Nicht alle kennen rapidshare wo sie hunderte von zips herunterladen. auch das splitten wäre zusätzlicher aufwand. ich habe nun noch andere ansätze gefunden jedoch noch nicht testen können:
ftp size:
http://php.net/manual/kr/function.ftp-size.php
 
Zurück
Oben