Hi,

Today we are going to learn about force downloading prompt in PHP.

While i am doing my projects, i had a requirement for file download, File type will be changed, So i made a research on this and made simple useful script which can be use any where to prompt download by giving path and file name . Let us create a function download_file and pass full file path and filename , we can use third argument to mention the MIME Type of file

download_file($sourceFile, $fileName, $mime_type = '') 

Next we can check whether we have permission to read the file.if not it will return 404 error

 if (!is_readable($sourceFile)) {
        header("HTTP/1.1 404 Not Found");
        return;
    }

Now we are going to create an array of list of mime types. so we can compare with this array and set correct header content type

 $mime_types_list = array(
        "gif" => "image/gif",
        "png" => "image/png",
        "jpeg" => "image/jpg",
        "jpg" => "image/jpg",
        "pdf" => "application/pdf",
        "csv" => "application/csv",
        "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",
        "php" => "text/plain"
    );

Next we are going to set mime type if we already pass the MIME type into function it will take that MIME ,else we are going to use a function pathinfo to retrieve the extension of file and we will compare with already created array to get content type

 $path_parts = pathinfo($sourceFile); //pathinfo 



    if ($mime_type == '') {

        $file_extension = $path_parts['extension'];
        if (array_key_exists($file_extension, $mime_types_list)) {
            $mime_type = $mime_types_list[$file_extension];
        } else {
            $mime_type = "application/force-download";
        };
    };

After that we will clean and start the output buffer

  @ob_end_clean();

Then we can set the content type and headers

if (ini_get('zlib.output_compression'))
        ini_set('zlib.output_compression', 'Off');

    header('Content-Type: ' . $mime_type);
    header('Content-Disposition: attachment; filename="' . $fileName . '"');
    header("Content-Transfer-Encoding: binary");
    header('Accept-Ranges: bytes');
    header("Cache-control: private");
    header('Pragma: private');

lastly we are going to read each line by line and print that as shown below.

$chunksize = 1 * (1024 * 1024);
    $bytes_send = 0;
    if ($sourceFile = fopen($sourceFile, 'r')) {


        while (!feof($sourceFile) &&
        (!connection_aborted())
        ) {
            $buffer = fread($sourceFile, $chunksize);
            print($buffer); // is also possible
            flush();
        }
        fclose($sourceFile);
    } else {
        header("HTTP/1.1 505 Internal server error");
        return;
    }

That is it !!!!! Now we can have a look, How we can read the file using created function We can make a path file and the name we want to give while downloading and pass to function . It will download prompt for file. example for reading file and download prompt

$filepath = 'sample.pdf';
$filename = 'sample.pdf';

download_file($filepath, $filename);
exit;
?>

Full code

<?php

/**
 * function to download a file from server
 * 
 * list all the values in grid
 * 
 * @auther Shabeeb  <me@blog.shabeebk.com >
 * @createdon   : 06-08-2014
 * @
 * 
 * @param source $sourceFile : file pathe 
 * @param source $fileName : file name for download 
 * @param source $mime_type : MIME type optional field
 * @return type
 * exceptions
 * 
 * 
 */
function download_file($sourceFile, $fileName, $mime_type = '') {

    if (!is_readable($sourceFile)) {
        header("HTTP/1.1 404 Not Found");
        return;
    }

    $size = filesize($sourceFile);
    $fileName = rawurldecode($fileName);


    $mime_types_list = array(
        "gif" => "image/gif",
        "png" => "image/png",
        "jpeg" => "image/jpg",
        "jpg" => "image/jpg",
        "pdf" => "application/pdf",
        "csv" => "application/csv",
        "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",
        "php" => "text/plain"
    );

    $path_parts = pathinfo($sourceFile); //pathinfo 



    if ($mime_type == '') {

        $file_extension = $path_parts['extension'];
        if (array_key_exists($file_extension, $mime_types_list)) {
            $mime_type = $mime_types_list[$file_extension];
        } else {
            $mime_type = "application/force-download";
        };
    };

    @ob_end_clean();

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

    header('Content-Type: ' . $mime_type);
    header('Content-Disposition: attachment; filename="' . $fileName . '"');
    header("Content-Transfer-Encoding: binary");
    header('Accept-Ranges: bytes');
    header("Cache-control: private");
    header('Pragma: private');


    $chunksize = 1 * (1024 * 1024);
    $bytes_send = 0;
    if ($sourceFile = fopen($sourceFile, 'r')) {


        while (!feof($sourceFile) &&
        (!connection_aborted())
        ) {
            $buffer = fread($sourceFile, $chunksize);
            print($buffer); // is also possible
            flush();
        }
        fclose($sourceFile);
    } else {
        header("HTTP/1.1 505 Internal server error");
        return;
    }

    die();
}

$filepath = 'sample.pdf';
$filename = 'sample.pdf';

download_file($filepath, $filename);
exit;
?>

Download the source

 4,707 total views