2010-02-23 15 views
5

Versuch zu zwingen-Download-Datei mit PHP üblich:Gibt es eine Grenze für die Größe einer Datei, wenn ein Download mit PHP ausgelöst wird?

header("Content-type: $type"); 
header("Content-Disposition: attachment; filename=$name"); 
header('Content-Length: ' . filesize($path)); 

Und es tut erfolgreich für Dateien irgendwo unter 32 mb. Für größere gibt es nur zeroed Datei zurück.

Offensichtlich gibt es eine Art Grenze, aber was setzt es? Mit Apache 2.2.11 und PHP 5.3.0.

+0

PHP hat keine solche Grenze. Dies sollte bei Serverfault abgefragt werden, da es sich auf Ihre Apache-Konfiguration bezieht. – hobodave

Antwort

0

Innerhalb der php.ini sehen Sie die Einstellung.

Ich kann mich nicht mehr an den Namen der Option erinnern, aber ich werde jetzt in meine php.ini schauen und versuchen, sie zu finden.

Entfernen Sie es einfach und es wird funktionieren.

Added

Okay, jemand bitte korrigieren Sie mich, wenn ich falsch bin, aber ist es

memory_limit

+0

Was? PHP hat keine "Max-Download" -Einstellung eines beliebigen Typs. Bitte nehmen Sie sich die Zeit, um Ihre Antwort zu recherchieren, damit Sie tatsächlich _provide_ liefern können. – hobodave

+0

Ich denke, das Problem ist, weil er die Datei selbst erzeugt, daher die memory_limit oben. Bitte korrigieren Sie mich, wenn ich falsch liege, da ich das auch wissen möchte. – Layke

+1

Es sind nicht genügend Informationen vorhanden, um das zu bestimmen. memory_limit hängt davon ab, wie viel Speicher das Skript verwenden kann. Dies würde nur ins Spiel kommen, wenn Sie versuchen würden, die gesamte Datei in den Speicher zu schreiben, oder genug davon, um die memory_limit zu überschreiten. Das Senden von Kopfzeilen führt dies nicht durch. – hobodave

3

Es scheint, wie Sie die gesamte Datei in den RAM sind das Laden vor dem Senden es bis zum Empfänger. Sie sollten in PHP-Streams suchen, um den gesamten Dateiinhalt senden zu können, ohne zuerst alles im RAM lesen zu müssen: http://php.net/streams

+0

Ich benutze fopen, fread ($ fh, $ chunksize), fclose-Funktionen. Sind sie in solchen Fällen nicht sicher? – jayarjo

+0

Die einfachste Form ist 'readfile' zu ​​verwenden http://php.net/manual/en/function.readfile.php – deceze

+0

Das ist ein guter Punkt deceze; Ich bin daran gewöhnt, Daten aus einer Datenbank oder einer anderen Quelle zu leiten, sodass ich auf Streams zurückgreifen kann, wenn eine einfachere Lösung verfügbar ist. – MightyE

8

Ich bin schließlich auf diesen Beitrag gestoßen: http://w-shadow.com/blog/2007/08/12/how-to-force-file-download-with-php/.

function output_file($file, $name, $mime_type='') 
{ 
/* 
This function takes a path to a file to output ($file), 
the filename that the browser will see ($name) and 
the MIME type of the file ($mime_type, optional). 

If you want to do something on download abort/finish, 
register_shutdown_function('function_name'); 
*/ 
if(!is_readable($file)) die('File not found or inaccessible!'); 

$size = filesize($file); 
$name = rawurldecode($name); 

/* Figure out the MIME type (if not specified) */ 
$known_mime_types=array(
    "pdf" => "application/pdf", 
    "txt" => "text/plain", 
    "html" => "text/html", 
    "htm" => "text/html", 
    "exe" => "application/octet-stream", 
    "zip" => "application/zip", 
    "doc" => "application/msword", 
    "xls" => "application/vnd.ms-excel", 
    "ppt" => "application/vnd.ms-powerpoint", 
    "gif" => "image/gif", 
    "png" => "image/png", 
    "jpeg"=> "image/jpg", 
    "jpg" => "image/jpg", 
    "php" => "text/plain" 
); 

if($mime_type==''){ 
    $file_extension = strtolower(substr(strrchr($file,"."),1)); 
    if(array_key_exists($file_extension, $known_mime_types)){ 
     $mime_type=$known_mime_types[$file_extension]; 
    } else { 
     $mime_type="application/force-download"; 
    }; 
}; 

ob_end_clean(); //turn off output buffering to decrease cpu usage 

// required for IE, otherwise Content-Disposition may be ignored 
if(ini_get('zlib.output_compression')) 
    ini_set('zlib.output_compression', 'Off'); 

header('Content-Type: ' . $mime_type); 
header('Content-Disposition: attachment; filename="'.$name.'"'); 
header("Content-Transfer-Encoding: binary"); 
header('Accept-Ranges: bytes'); 

/* The three lines below basically make the 
    download non-cacheable */ 
header("Cache-control: private"); 
header('Pragma: private'); 
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); 

// multipart-download and download resuming support 
if(isset($_SERVER['HTTP_RANGE'])) 
{ 
    list($a, $range) = explode("=",$_SERVER['HTTP_RANGE'],2); 
    list($range) = explode(",",$range,2); 
    list($range, $range_end) = explode("-", $range); 
    $range=intval($range); 
    if(!$range_end) { 
     $range_end=$size-1; 
    } else { 
     $range_end=intval($range_end); 
    } 

    $new_length = $range_end-$range+1; 
    header("HTTP/1.1 206 Partial Content"); 
    header("Content-Length: $new_length"); 
    header("Content-Range: bytes $range-$range_end/$size"); 
} else { 
    $new_length=$size; 
    header("Content-Length: ".$size); 
} 

/* output the file itself */ 
$chunksize = 1*(1024*1024); //you may want to change this 
$bytes_send = 0; 
if ($file = fopen($file, 'r')) 
{ 
    if(isset($_SERVER['HTTP_RANGE'])) 
    fseek($file, $range); 

    while(!feof($file) && 
     (!connection_aborted()) && 
     ($bytes_send<$new_length) 
     ) 
    { 
     $buffer = fread($file, $chunksize); 
     print($buffer); //echo($buffer); // is also possible 
     flush(); 
     $bytes_send += strlen($buffer); 
    } 
fclose($file); 
} else die('Error - can not open file.'); 

die(); 
} 

/********************************************* 
      Example of use 
**********************************************/ 

/* 
Make sure script execution doesn't time out. 
Set maximum execution time in seconds (0 means no limit). 
*/ 
set_time_limit(0); 
$file_path='that_one_file.txt'; 
output_file($file_path, 'some file.txt', 'text/plain'); 

Hinzufügen alle Header dort empfohlen und auch mit:

ob_end_clean(); //turn off output buffering to decrease cpu usage 

vor jedem Ausgang - geholfen hat. Keine Einschränkungen mehr beobachtbar. Dateien laden sich sogar riesige herunter.

+0

Die Verwendung von '@' Fehler Unterdrückung ist nicht ratsam, da es langsam ist und zum Debuggen von Albträumen führen kann. –

+0

Haben Sie es entfernt, danke für das Aufzeigen dieser :) – jayarjo

+2

#giveThisMan_a_bells! Danke @Jayarjo, das hat es für mich gelöst! –

0

auch müssen möglicherweise set_time_limit(0);

0

Es build 1-GB-Grenze ist in Apache, auch wenn u wird versuchen, eine Datei aus er Stammverzeichnis zum Download, vollständig php zu vermeiden.

Verwandte Themen