25 November 2009

A simple file download script in PHP

When you have a download link to a .zip / .exe file on your website, it normally ask to download the file to a location on the client-side's computer. For .txt / .pdf / .gif etc. files it normally opens in the browser itself, provided it has support for it.

If you ever need to force the file to be download, you can easily do this in PHP. Below is the script which will force all file specified to be downloaded to the client-side's computer rather than open in the browser itself:

<?php

$filename = $_GET['filename'];

// required for IE, otherwise Content-disposition is ignored
if(ini_get('zlib.output_compression')){
    ini_set('zlib.output_compression', 'Off');
}

$file_extension = strtolower(substr(strrchr($filename, "."), 1));

if($filename == ""){

?>
    <html>
        <head>
            <title>File Download</title>
        </head>
        <body>
            ERROR: No filename specified.
        </body>
    </html>
<?

    exit;

}elseif(!file_exists($filename)){

?>
    <html>
        <head>
            <title>File Download</title>
        </head>
        <body>
            ERROR: File not found.
        </body>
    </html>
<?

    exit;

}
switch($file_extension){
    case "pdf":
        $contentType = "application/pdf";
    break;
    case "exe":
        $contentType = "application/octet-stream";
    break;
    case "zip":
        $contentType = "application/zip";
    break;
    case "doc":
        $contentType = "application/msword";
    break;
    case "xls":
        $contentType="application/vnd.ms-excel";
    break;
    case "ppt":
        $contentType = "application/vnd.ms-powerpoint";
    break;
    case "gif":
        $contentType = "image/gif";
    break;
    case "png":
        $contentType = "image/png";
    break;
    case "jpeg":
    case "jpg":
        $contentType = "image/jpg";
    break;
    default:
        $contentType = "application/force-download";
}
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Type: ".$contentType);
header("Content-Disposition: attachment; filename=\"".basename($filename)."\";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filename));
readfile($filename);
exit;

?>

No comments: