PHP File Upload and Download Script

Here you will find file upload and download php script. First I have provided the code you can use directly and then very important tips and facts about each issues.

You will find detail descriptions of parameters, both client and server side, affecting upload and download of files. Example will show how to store MSWord file in database and also how to upload PDF file to server. Change it little bit and it will work for all types of files.

A. PHP File Upload Script

<TITLE> PHP File Upload Script </TITLE>
if( isset($_POST['submit1'])) {
// $_FILES is the array auto filled when you upload a file and submit a form.
$userfile_name = $_FILES['file1']['name']; // file name
$userfile_tmp  = $_FILES['file1']['tmp_name']; // actual location
$userfile_size  = $_FILES['file1']['size']; // file size
$userfile_type  = $_FILES['file1']['type']; // mime type of file sent by browser. PHP doesn't check it.
$userfile_error  = $_FILES['file1']['error']; // any error!. get from here
// Content uploading.
$file_data = '';
if ( !empty($userfile_tmp))
// We encode the data just to make it more database friendly
$file_data = base64_encode(@fread(fopen($userfile_tmp, 'r'), filesize($userfile_tmp) ) );
switch (true)
// Check error if any
case ($userfile_error == UPLOAD_ERR_NO_FILE):
case empty($file_data):
echo 'You must select a document to upload before you can save this page.';
case ($userfile_error == UPLOAD_ERR_INI_SIZE):
case ($userfile_error == UPLOAD_ERR_FORM_SIZE):
echo 'The document you have attempted to upload is too large.';
case ($userfile_error == UPLOAD_ERR_PARTIAL):
echo 'An error occured while trying to recieve the file. Please try again.';
if( !empty($userfile_tmp))
// only MS office and text file is accepted.
if( !(($userfile_type=="application/msword") || ($userfile_type=="text/plain")) )
{echo 'Your File Type is:'. $userfile_type;
echo '<br>File type must be text(.txt) or msword(.doc).';
echo filesize($userfile_tmp);
<form name="profile" method="POST" action="<?php echo $_SERVER['PHP_SELF'] ?>" target="_self" enctype="multipart/form-data" >
<P align ="center"><input type="hidden" name="MAX_FILE_SIZE" value="1000000">
<input type="file" name="file1" value="AttachFile" device="files" accept="text/*" tabindex=18 >
<input type="submit" name="submit1" value="Submit" />

Important Tips:

  • Form enctype="multipart/form-data"
  • MAX_FILE_SIZE - hidden input element with name=MAX_FILE_SIZE is used to check filesize in browser itself.
  • device="files" accept="text/*" - accept specifies mime types.
  • post_max_size, upload_max_filesize and memory_limit are php.ini settings.
  • post_max_size should be greater than upload_max_size.
  • If post_max_size is less than size of posted data then $_POST and $_FILES superglobals are empty.
  • max_input_time sets the max time in seconds, the script is allowed to receive input; this include file uploads. - also php.ini settings.
  • Check for enctype="multipart/form-data" in your form tag, if unavailable your file will not be available to your server. and you will see $_FILES empty.
  • Check name in your <input type="file">, if unavailable your $_FILES will again show nothing in it.

B. PHP File Download Script:

Download PDF file

// your file to upload
$file = '2007_SalaryReport.pdf';
header("Expires: 0");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Content-type: application/pdf");
// tell file size
header('Content-length: '.filesize($file));
// set file name
header('Content-disposition: attachment; filename='.basename($file));
// Exit script. So that no useless data is output-ed.

Generate data for Excel and prompt for Downloading Excel file

Sometimes you want to give dynamically produced data to user. If you are giving dynamically generated content data to user then you have to buffer all your data until your all data is ready for download. If you do not do this then your data will not output for download correctly. or probably you will get lots of download pop-up.

// file name to be appear in output name. User can change their file name
// but this will give him a option for file name.
$file = 'testExcelFile.xls';
// start buffring
// sample dynamically generated data
echo '<table border="1"> ';
echo '<tr><th>Name</th><th>Age</th></tr>';
for ($i=0; $i<=5; $i++) {     echo "<tr><td>Name$i</td><td>".($i+1)."</td></tr>";
echo '</table>';
$content = ob_get_contents();
header("Expires: 0");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Content-type: application/;charset:UTF-8");
header('Content-length: '.strlen($content));
header('Content-disposition: attachment; filename='.basename($file));
// output all contents
echo $content;
exit; // If any tags/things not supported by excel will output then it will try to //open in office word

- Check data output. If you output any data to browser before header(); then header will not set.
- Check file permission if you are getting error in reading the file content.
- You must also provide link to file to be download to user so that they can download your file if for any reason your download script is not working.
<a href=''>For downloading click here</a>
In this case your file will be downloaded using you provided link. The file will be opened if your file type is associated/mapped in your users browser. Otherwise they will pop-up for download.

You can download any file this way. Just change the content-type headers.
You need to change the content-type header to your file type (MIME Type).
Use application/ for excel file download, appliacation/msword for MS Word file download. If you are not sure about the file type then you can use

Information about How to upload large file.

Liked! So, share it.

Update: Thanks timmy for correcting the info about mime type.

  • # 1 - by Kamran Saadatjoo

    Is there a way to capture the return value from readfile (in the first download script) to be sure that a file was indeed downloaded? The PHP reference manuals say that readfile returns the number of bytes read, but I don’t know how to access this return value and test it. I appreciate your help.

Comment pages
1 2 205
Comments are open for an year period. Please, write here on Facebook page.