Friday, February 14, 2014

File download script using PHP

Opening a file in another window or tab within a browser, we can use an anchor to that file like this : 

<a href="test.pdf" target="_blank">Download the PDF here</a>

it will open the file in a new tab. To force the browser to download it on the viewer's PC, we need to write some server side code. Here I am showing some sample codes which would show "Save As" message box on browsers.

Setting the headers is the most important thing here. Here, code for downloading PDF file is shown. We are reading "sample.pdf" and forcing the browser to download it as "test.pdf" on viewer's machine. We can have variety on our solutions.

Solution 1 ::

<?php

/// Set the header
header("Content-type:application/pdf"); 
header("Content-Transfer-Encoding: binary");
header("Content-Disposition:attachment; filename=test.pdf");

/// Deliver the content
readfile("sample.pdf");
?>

Solution 2 ::

<?php

// GET the Source file's contents
$str = file_get_contents("sample.pdf") or die("Could not open file");

// Get the Target
$fp = fopen("php://output","w+") or die("Could not open output stream");

// Set the Header
header("Content-type:application/pdf"); 
header("Content-Transfer-Encoding: binary");
header("Content-Disposition:attachment; filename=test.pdf");

// Send Data
fputs($fp, $str);

// Close file
fclose( $fp );
?>

Solution 3 ::

<?php

// GET the Source file
$fp = fopen("sample.pdf","r+") or die("Could not open file");

// Set the Header
header("Content-type:application/pdf"); 
header("Content-Transfer-Encoding: binary");
header("Content-Disposition:attachment; filename=test.pdf");

// Read and Send Data
while( !feof($fp) )
 echo fread( $fp, 1024 );

// Close file
fclose( $fp );
?>

All the above solutions would work smoothly but the first one needs output buffering to be enabled. The 3 solutions above have different file reading and rendering methods only, the header information remain same. We are reading a file called 'sample.pdf' and forcing it to be downloaded with a default name 'test.pdf'. 

The "Content-Disposition:attachment" is very important. This would prompt for downloading the file instead of directly showing it in Browser.  

We can force the browser to download other file types like Excel file but for that we need to modify the MIME 'Content-type' in response header. For an Excel file to be downloaded we may use the following code :

<?php

// GET the Source file
$filename  = "tester.xls";
$fp = fopen($filename,"r+") or die("Could not open file");

// Set the Header
header("Content-Type:application/vnd.ms-excel; charset=utf-8"); 
header("Content-Transfer-Encoding: binary");
header("Content-Disposition:attachment; filename=genuine.xls");

// Read and Send Data
echo fread( $fp, filesize($filename) );

// Close file
fclose( $fp );
?>

The above code will download all kind of files if we correctly change the "Content-Type" settings in header(). Some content types are shown below :

If the MIME type starts with "vnd" ( in case of .ppt, .word or .xls files ), it means to be vendor specific. If the type starts with "x-", it means that it is non-standard, ( not registered with the "Internet Assigned Numbers Authority" ).

Images :: 
.png : header("Content-Type:image/png") 
.jpg : header("Content-Type:image/jpg") 
.gif : header("Content-Type:image/gif") 
.bmp : header("Content-Type:image/bmp") 

Texts ::
.txt : header("Content-Type:text/plain") 
.html : header("Content-Type:text/plain") 
.php : header("Content-Type:text/plain") 
.js : header("Content-Type:text/plain") or header("Content-Type:text/javascript") (obsolete) or header("Content-Type:application/javascript")
.xml : header("Content-Type:text/xml")
.csv : header("Content-Type:text/csv")
.css : header("Content-Type:text/css")

Video ::
.mpg : header("Content-Type:video/mpeg")
.mp4 : header("Content-Type:video/mp4")
.3gp : header("Content-Type:video/3gpp")

Audio ::
.aac : header("Content-Type:audio/x-aac")
.mp3 : header("Content-Type:audio/mpeg")

Zip ::
.7z : header("Content-Type:application/x-7z-compressed")
.bz : header("Content-Type:application/x-bzip")
.zip : header("Content-Type:application/zip")

Other ::
.pdf : header("Content-Type:application/pdf")
.xls : header("Content-Type:application/vnd.ms-excel; charset=utf-8")
.ppt : header("Content-Type:vnd.ms-powerpoint")
.doc : header("Content-Type:application/vnd.openxmlformats-officedocument.wordprocessingml.document")
.swf : header("Content-Type:application/x-shockwave-flash")
.bin/.exe : header("Content-Type:application/octet-stream")

No comments: