Bestand forceren om te downloaden?

Hoe kan ik met PHP of JavaScript een force download maken? Ik heb bijvoorbeeld een afbeelding, maar ik wil dat als je op die link naar de afbeelding klikt dat ze niet in die pagina wordt geladen, maar begint te downloaden. Met bv een zip file is dat geen probleem, maar afbeeldingen, swf's, filmpjes en in veel browsers ook pdf's worden dan rechtstreeks geopend in een browservenster.

http://www.daniweb.com/code/snippet75.html

Aha, ziet er al goed uit. Maar moet ik dan voor elk bestandstype (.jpg, .tif, .pdf, .swf, ...) zo'n scritp maken. Of met een case werken?

Je kan ook een content-type: application/octet-stream sturen.

Nee dat hoeft niet,

bijvoorbeeld dit:
( $sys_file = de bestandsnaam + het pad vanaf /, $filename = de bestandsnaam )

[code:1:2bb965c13b]if (file_exists($sys_file)) {
// We gaan een download outputten
$fp = fopen($sys_file, ‘rb’);
// stuur de juiste headers
header(“Pragma: public”);
header(“Expires: 0”);
header(“Cache-Control: private”);
header(“Content-type: $doctype”);
header(“Charset: ISO-8859-1”);
header("Content-Length: ".filesize($sys_file));
header(“Content-Disposition: attachment; filename=$filename”);
// stuur de download door
if (!fpassthru($fp)) { header(“Location: index.php?msg=De download is mislukt.n”); }
}[/code:1:2bb965c13b]

De cache control is noodzakelijk omdat je bij XP in de download dialoog kan kiezen voor openen en opslaan en zonder cachecontrol kan het bestand niet worden geopend.

Wat is $doctype? De extentie van het bestand?

het is het mimetype vanaf php 4.3.0 kun je de functie [code:1:844c33616c] mime_content_type()[/code:1:844c33616c] gebruiken en anders de type property bij een file upload. Het is een stukje uit een downloadfunctie voor een CMS waarbij de mimetype tijdens de upload word vastgelegd in de database - ik had het over het hoofd gezien.

Dus ziet het er zo uit?

[code:1:d4277c02ed]

$filename = bestandsnaam;
$sys_file = /pad/naar/de/$filename;
$doctype = mime_content_type($sys_file);

if (file_exists($sys_file)) {
// We gaan een download outputten
$fp = fopen($sys_file, ‘rb’);
// stuur de juiste headers
header(“Pragma: public”);
header(“Expires: 0”);
header(“Cache-Control: private”);
header(“Content-type: $doctype”);
header(“Charset: ISO-8859-1”);
header("Content-Length: ".filesize($sys_file));
header(“Content-Disposition: attachment; filename=$filename”);
// stuur de download door
if (!fpassthru($fp)) {
header(“Location: index.php?msg=De download is mislukt.n”);
}
}
[/code:1:d4277c02ed]

[b:d4277c02ed][u:d4277c02ed]Update[/u:d4277c02ed][/b:d4277c02ed]

Ik heb het bovenstaande scritpt lopen testen, maar ik denk dat het beter is om de header voor Content-type beter te definieren. Vna de meeste bestanden maakt hij .txt bestanden, van een .fla maakt hij een .doc, een .dmg herkent hij helemaal niet en een .ai bewaart hij als pdf (dat laatste is niet zo gek natuurlijk).

Dus toch beter met een switch werken hier? Hoe moet ik de bestandstypes definieren?

Zip files doen het wel goed, maar alle bestanden houden op bij 2Mb. Maar dat ligt aan m’n php instellingen geloof ik hé? Waarom staat dat standaard om 2Mb en is het erg als ik dat verhoof tot bv 100Mb?

je kunt een array maken waarin je de extensie als key gebruikt en de mimetype als value dus bv.:

[code:1:ee5285259b]$arrMime = array("html"=>"text/html")[/code:1:ee5285259b]
aanvullen voor elk bestandstype dat je wilt gebruiken.
je kunt met

[code:1:ee5285259b]uit de php documentatie:
$path_parts = pathinfo("/www/htdocs/index.html");
echo $path_parts["dirname"] . "n";
echo $path_parts["basename"] . "n";
echo $path_parts["extension"] . "n";[/code:1:ee5285259b]
de extensie ophalen enzo het juiste mimetype selecteren.

[code:1:ee5285259b]$doctype = $arrMime[$path_parts[‘extension’]];[/code:1:ee5285259b]
Op deze manier bepaal je zelf welke soort bestanden er gedownload kunnen worden, als de extensie niet in de array zit -> geen download!