Connecting Tech Pros Worldwide Help | Site Map

Uploading files into a MySQL database using PHP

 
Old November 23rd, 2007, 05:21 AM
Atli's Avatar
Moderator
 
Join Date: Nov 2006
Location: Iceland
Posts: 3,701
Introduction
You may be asking yourself: "Why put files inside my database? Why not just put them on the file-system?".
In most cases, that is exactly what you should do. It's simple, effective, and requires very little effort on your part.

There are, however, some special circumstances that do require a little more complex tactics.
For example, when handling sensitive data, putting the files into a database gives you a little more control over how the data is handled and who has access to it.

This article shows a simple way of putting files into a MySQL table, using PHP.

Before you start
To get through this smoothly, you should be familiar with the following:
The battle plan
As with all programs, before we start writing we need to plan a little ahead. Just so we know what we are going to write before we write it.

Before we start on the program, we need to design the database. This is not a complex design, as we are not talking about creating some complex filing system. We only need a single table, containing a BLOB field for our file and various other fields to store information on our file, such as name, size, type.

Now then. The first phase of the program is getting the file from our users onto the server where our PHP can interact with it. This is the simplest part of the process, requiring only a basic HTML form.

The second phase involves reading the uploaded file, making sure it was uploaded successfully and adding it to the database. This is a similar process as the one used when uploading a file to the file-system, but using the MySQL functions rather than the file-system functions.

The third phase is to list all files that have been uploaded and saved on the database, with a link so it can be downloaded. The only problem here would be the fact that the file does not exists on the server, so how do we create a link to it? That is a problem handled by phase 4, all we need to do in phase 3 is create a link with the ID of the file to be downloaded embedded in the URL.

The fourth, and final, part is the one that is most confusing about this process. The part where we fetch the file and send it to the client's browser.
We start by using the MySQL functions, and the ID sent by phase 3, to fetch the file data from the database. Then we set a few headers, letting the browser know what to expect, before finally sending the contents of the file.

Now, using this summary as a guide, lets start writing our program.

Phase 0: Building a database
The database is simple. One table with a BLOB field for the file data and a few fields for various pieces of information relating to the file:
Expand|Select|Wrap|Line Numbers
  1. CREATE TABLE FileStorage (
  2.   FileID Int Unsigned Not Null Auto_Increment,
  3.   FileName VarChar(255) Not Null Default 'Untitled.txt',
  4.   FileMime VarChar(50) Not Null Default 'text/plain',
  5.   FileSize BigInt Unsigned Not Null Default 0,
  6.   FileData MediumBlob Not Null,
  7.   Created DateTime Not Null,
  8.   PRIMARY KEY (FileID)
  9. )
  10.  
As you see, we store the file name, including the extension.
We have the mime type, which we use to let the browser know what kind of file we are dealing with.
The size of the file in bytes.
And finally the data itself, in a MediumBlob field.

Phase 1: Uploading the file
Now, we need to get the file from the user. The table we designed does not require any additional information from the user, so we will make this simple and create a HTML form with only a single "file" input field and a submit button:
Expand|Select|Wrap|Line Numbers
  1. <form action="add_file.php" method="post" enctype="multipart/form-data">
  2.     <input type="file" name="uploaded_file" /><br />
  3.     <input type="submit" value="Upload file" />
  4. </form>
  5.  
  6. <p>
  7.     <a href="list_files.php">See all files</a>
  8. </p>
  9.  
Note the third attribute of the <form> element, "enctype". This tells the browser how to send the form data to the server. As it is, when sending files, this must be set to "multipart/form-data".
If it is set any other way, or not set at all, your file is probably not going to be transmitted correctly.

At the bottom, we have a link to the list we will create in phase 3.

Phase 2: Add the file to the database
In the form we built in phase 1, we set the action property to "add_file.php". This is the file we are going to build it this phase of the process.

This file needs to check if a file has been uploaded, make sure it was uploaded without errors, and add it to the database:
Expand|Select|Wrap|Line Numbers
  1. <?php
  2. # Check if a file has been uploaded
  3. if(isset($_FILES['uploaded_file'])) 
  4. {
  5.     # Make sure the file was sent without errors
  6.     if($_FILES['uploaded_file']['error'] == 0) 
  7.     {
  8.         # Connect to the database
  9.         $dbLink = mysqli_connect("127.0.0.1", "user", "pwd", "dbName");
  10.         if(mysqli_connect_errno()) {
  11.             die("MySQL connection failed: ". mysqli_connect_error());
  12.         }
  13.  
  14.         # Gather all required data
  15.         $name = mysqli_real_escape_string($dbLink, $_FILES['uploaded_file']['name']);
  16.         $mime = mysqli_real_escape_string($dbLink, $_FILES['uploaded_file']['type']);
  17.         $size = $_FILES['uploaded_file']['size'];
  18.         $data = mysqli_real_escape_string($dbLink, file_get_contents($_FILES  ['uploaded_file']['tmp_name']));
  19.  
  20.         # Create the SQL query
  21.         $query = "
  22.             INSERT INTO FileStorage (
  23.                 FileName, FileMime, FileSize, FileData, Created
  24.             )
  25.             VALUES (
  26.                 '{$name}', '{$mime}', {$size}, '{$data}', NOW()
  27.             )";
  28.  
  29.         # Execute the query
  30.         $result = mysqli_query($dbLink, $query);
  31.  
  32.         # Check if it was successfull
  33.         if($result) 
  34.         {
  35.             echo "Success! Your file was successfully added!";
  36.         }
  37.         else 
  38.         {
  39.             echo "Error! Failed to insert the file";
  40.             echo "<pre>". mysqli_error($dbLink) ."</pre>";
  41.         }
  42.     }
  43.     else 
  44.     {
  45.         echo "Error! 
  46.                 An error accured while the file was being uploaded. 
  47.                 Error code: ". $_FILES['uploaded_file']['error'];
  48.     }
  49.  
  50.     # Close the mysql connection
  51.     mysqli_close($dbLink);
  52. }
  53. else 
  54. {
  55.     echo "Error! A file was not sent!";
  56. }
  57.  
  58. # Echo a link back to the mail page
  59. echo '<p>Click <a href="index.html">here</a> to go back</p>';
  60. ?>
  61.  
Phase 3: Listing all existing files
So, now that we have a couple of files in our database, we need to create a list of files and link them so they can be downloaded:
Expand|Select|Wrap|Line Numbers
  1. <?php
  2. # Connect to the database
  3. $dbLink = mysqli_connect("127.0.0.1", "user", "pwd", "dbName");
  4. if(mysqli_connect_errno()) {
  5.     die("MySQL connection failed: ". mysqli_connect_error());
  6. }
  7.  
  8. # Query for a list of all existing files
  9. $result = mysqli_query($dbLink, "SELECT FileID, FileName, FileMime, FileSize, Created FROM FileStorage");
  10.  
  11. # Check if it was successfull
  12. if($result) 
  13. {
  14.  
  15.     # Make sure there are some files in there
  16.     if(mysqli_num_rows($result) == 0) {
  17.         echo "<p>There are no files in the database</p>";
  18.     }
  19.     else
  20.     {
  21.         # Print the top of a table
  22.         echo "<table width='100%'><tr>";
  23.         echo "<td><b>Name</b></td>";
  24.         echo "<td><b>Mime</b></td>";
  25.         echo "<td><b>Size (bytes)</b></td>";
  26.         echo "<td><b>Created</b></td>";
  27.         echo "<td><b>&nbsp;</b></td>";
  28.         echo "</tr>";
  29.  
  30.         # Print each file
  31.         while($row = mysqli_fetch_assoc($result))
  32.         {
  33.             # Print file info
  34.             echo "<tr><td>". $row['FileName']. "</td>";
  35.             echo "<td>". $row['FileMime']. "</td>";
  36.             echo "<td>". $row['FileSize']. "</td>";
  37.             echo "<td>". $row['Created']. "</td>";
  38.  
  39.             # Print download link
  40.             echo "<td><a href='get_file.php?id=". $row['FileID'] ."'>Download</a></td>";
  41.             echo "</tr>";
  42.         }
  43.  
  44.         # Close table
  45.         echo "</table>";
  46.     }
  47.  
  48.     # Free the result
  49.     mysqli_free_result($result);
  50. }
  51. else 
  52. {
  53.     echo "Error! SQL query failed:";
  54.     echo "<pre>". $dbLink->error ."</pre>";
  55. }
  56.  
  57. # Close the mysql connection
  58. mysqli_close($dbLink);
  59. ?>
  60.  
Phase 4: Downloading a file
This part is the one that usually causes the most confusion.

To really understand how this works, you must understand how your browser downloads files. When a browser requests a file from a HTTP server, the server response will include information on what exactly it contains. These bits of information are called headers. The headers usually include information on the type of data being sent, the size of the response, and in the case of files, the name of the file.

There are of course a lot of other headers, which I will not cover here, but it is worth looking into!

Now, this code. We start simply by reading the ID sent by the link in phase 3. If the ID is valid, we fetch the information on the file who's ID we received, send the headers, and finally send the file data:
Expand|Select|Wrap|Line Numbers
  1. <?php
  2. # Make sure an ID was passed
  3. if(isset($_GET['id']))
  4. {
  5.     # Get the ID
  6.     $id = $_GET['id'];
  7.  
  8.     # Make sure the ID is in fact a valid ID
  9.     if(!is_numeric($id) || ($id <= 0)) {
  10.         die("The ID is invalid!");
  11.     }
  12.  
  13.     # Connect to the database
  14.     $dbLink = mysqli_connect("127.0.0.1", "user", "pwd", "dbName");
  15.     if(mysqli_connect_errno()) {
  16.         die("MySQL connection failed: ". mysqli_connect_error());
  17.     }
  18.  
  19.     # Fetch the file information
  20.     $query = "
  21.         SELECT FileMime, FileName, FileSize, FileData 
  22.         FROM fileStorage 
  23.         WHERE FileID = {$id}";
  24.  
  25.     $result = @mysqli_query($dbLink, $query)
  26.         or die("Error! Query failed: <pre>". mysqli_error($dbLink) ."</pre>");
  27.  
  28.     # Make sure the result is valid
  29.     if(mysqli_num_rows($result) == 1)
  30.     {
  31.         # Get the row
  32.         $row = mysqli_fetch_assoc($result);
  33.  
  34.         # Print headers
  35.         header("Content-Type: ". $row['FileMime']);
  36.         header("Content-Length: ". $row['FileSize']);
  37.         header("Content-Disposition: attachment; filename=". $row['FileName']);
  38.  
  39.         # Print data
  40.         echo $row['FileData'];
  41.     }
  42.     else
  43.     {
  44.         echo "Error! No image exists with that ID.";
  45.     }
  46.  
  47.     # Free the mysqli resources
  48.     @mysqli_free_result($result);
  49.     @mysqli_close($dbLink);
  50.  
  51. }
  52. else
  53. {
  54.     echo "Error! No ID was passed.";
  55. }
  56. ?>
  57.  
Any decent browser should be able to read the headers and understand what type of file this is, and that it is to be downloaded, not opened.

The finish line
So, as you see, this is not as complex as one might think.

This code is of course only written for demonstration purposes and I would not recommend using it without adding a little extra security. Un-edited, this code would basically allow anybody to upload anything to your server, which is not a good idea!

I hope this has been helpful, and I wish you all the best.

See you around,
- Atli Þór

Edits
  • August 20th, 2008 - Replaced the old mysql functions with the improved mysqli functions.
    In order to keep the code as easy to understand as possible, I still retain the procedural style of the old mysql functions, even tho the mysqli extension provides an OOP version.



  #51  
Old June 19th, 2009, 11:42 AM
Newbie
 
Join Date: Jun 2009
Posts: 26

re: Uploading files into a MySQL database using PHP


Ok, and thank you very much on all your help.
Ooops, I just want to ask... Is this uploading codes can support mp4 and mp3 files? I already increase my upload and post_max_size.

Thanks..
  #52  
Old June 19th, 2009, 11:51 AM
Atli's Avatar
Moderator
 
Join Date: Nov 2006
Location: Iceland
Posts: 3,701

re: Uploading files into a MySQL database using PHP


This code can upload any file, regardless of size, type or extension.

If your PHP and MySQL setup is set up to handle large file uploads, then this code can process them.
  #53  
Old June 22nd, 2009, 04:22 AM
Newbie
 
Join Date: Jun 2009
Posts: 4

re: Uploading files into a MySQL database using PHP


Hello..

Can anyone know why this error is present:
Quote:
Fatal error: Call to undefined function mysqli_connect() in c:\Inetpub\wwwroot\uploading\connect.php on line 20
Code in line 20:
Expand|Select|Wrap|Line Numbers
  1. $dbLink = mysqli_connect('localhost', 'root', 'ai3', 'filestorage');
Thanks..
  #54  
Old June 22nd, 2009, 07:14 AM
Newbie
 
Join Date: Jun 2009
Posts: 4

re: Uploading files into a MySQL database using PHP


Hello..

Why does the error "Error, Failed to insert the File."

Thank you..
  #55  
Old June 22nd, 2009, 11:36 AM
Atli's Avatar
Moderator
 
Join Date: Nov 2006
Location: Iceland
Posts: 3,701

re: Uploading files into a MySQL database using PHP


Hi, apple.
Quote:
Originally Posted by apple08 View Post
Hello..

Can anyone know why this error is present:
Quote:
Fatal error: Call to undefined function mysqli_connect() in c:\Inetpub\wwwroot\uploading\connect.php on line 20
Code in line 20:
Expand|Select|Wrap|Line Numbers
  1. $dbLink = mysqli_connect('localhost', 'root', 'ai3', 'filestorage');
Thanks..
This error occurs when you try to use a function belonging to an extension that isn't loaded (or doesn't exist).

In this case, your PHP installation is missing the Improved MySQL extension
See the Installation page in the manual of instructions on how to enable the extension.

You can also rewrite the code to use the old MySQL extension, if that is available in your installation.
You would just have to rewrite the connection part and remove the "i" from the other functions.

Quote:
Originally Posted by apple08 View Post
Hello..

Why does the error "Error, Failed to insert the File."

Thank you..
That is the error I wrote into my example code in case the SQL query that is supposed to insert the file failed.
It should have printed additional information that would be good to have if you want our help debugging this.
  #56  
Old June 23rd, 2009, 08:28 AM
Newbie
 
Join Date: Jun 2009
Posts: 4

re: Uploading files into a MySQL database using PHP


Hello,

To be specific, the error I encountered was " Error, failed to insert the File. MySQL server has gone away." There are also times that the error was " Error, failed to insert the File. Got a packet larger than the max_allowed_packet bytes."

That said errors only occur when I tried to upload a file larger than 2Mb.

Thank you.
  #57  
Old June 23rd, 2009, 10:51 AM
Atli's Avatar
Moderator
 
Join Date: Nov 2006
Location: Iceland
Posts: 3,701

re: Uploading files into a MySQL database using PHP


That would indicate that you are sending more data than MySQL is willing to accept.

You need to alter the MySQL configuration so that it can accept more data.
The "max_allowed_packet" directive is a good place to start.

The MySQL configuration file is named "my.cnf" (or "my.ini", on Windows).
It is usually just under the MySQL installation dir, although that can vary based on the installation type.
  #58  
Old June 25th, 2009, 07:27 AM
Newbie
 
Join Date: Jun 2009
Posts: 4

re: Uploading files into a MySQL database using PHP


Hello, do you guys know how I can make the list of my uploaded files become a thumbmails instead of table list?

Thanks.
  #59  
Old June 25th, 2009, 07:37 AM
Newbie
 
Join Date: Jun 2009
Posts: 26

re: Uploading files into a MySQL database using PHP


Hi...

I just want to ask why does my server is too slow whenever I upload a quite large fie. Is it because I save the file to the database.

Thank you....
  #60  
Old June 30th, 2009, 05:47 PM
Newbie
 
Join Date: Mar 2009
Posts: 6

re: Uploading files into a MySQL database using PHP


Hi,

I have a question about the list files, Is there a way to list only the field TYPE ='FYR' instead list all the record. Any help will be appreciated.

Thank you in advance.

msei
  #61  
Old June 30th, 2009, 09:19 PM
Atli's Avatar
Moderator
 
Join Date: Nov 2006
Location: Iceland
Posts: 3,701

re: Uploading files into a MySQL database using PHP


Hi.

If you added an additional field named TYPE, then you would just have to add a where clause to the SQL query specifying the values you want listed.
Expand|Select|Wrap|Line Numbers
  1. SELECT ... FROM `FileStorage` WHERE `TYPE` = 'FYR'
  #62  
Old August 9th, 2009, 02:36 PM
Newbie
 
Join Date: Aug 2009
Posts: 2

re: Uploading files into a MySQL database using PHP


Hi Atli. I tried pasting your codings to my final project and it worked just fine. However, how can i download the file and open them successfully especially with .doc files? Sorry i need to know the step by step procedures. I tried following the phase 4 but still couldn't understand. Thanks in advance.
  #63  
Old August 12th, 2009, 06:06 AM
Atli's Avatar
Moderator
 
Join Date: Nov 2006
Location: Iceland
Posts: 3,701

re: Uploading files into a MySQL database using PHP


Hi xaralee.

The code in phase #4 should successfully send *any* type of file back to the browser.
This is obviously dependent on whether or not the browser sent the correct mime-type and extension when you uploaded the file, but I doubt any decent browser would fail to do that with a Word document.

How the browser actually handles the downloaded file is not something this code can control. If you want the browser to open the .doc file in Word, then you will have to tell your browser to do that.

Most browsers give you a choice when downloading a file, whether to open it, and which application to use, or whether to download it.
  #64  
Old August 12th, 2009, 09:13 AM
Newbie
 
Join Date: Aug 2009
Posts: 2

re: Uploading files into a MySQL database using PHP


Quote:
Originally Posted by Atli View Post
Hi xaralee.

The code in phase #4 should successfully send *any* type of file back to the browser.
This is obviously dependent on whether or not the browser sent the correct mime-type and extension when you uploaded the file, but I doubt any decent browser would fail to do that with a Word document.

How the browser actually handles the downloaded file is not something this code can control. If you want the browser to open the .doc file in Word, then you will have to tell your browser to do that.

Most browsers give you a choice when downloading a file, whether to open it, and which application to use, or whether to download it.
Hi Atli. I solved the problem already. Thank you for your advice. (:
  #65  
Old September 2nd, 2009, 08:31 PM
Frinavale's Avatar
Site Moderator
 
Join Date: Oct 2006
Location: The Great White North :)
Posts: 4,940

re: Uploading files into a MySQL database using PHP


Atli this is an awesome article :)
You may want to include a links to the resources that you're using (like the mysqli extension) though :)
  #66  
Old September 11th, 2009, 04:58 AM
Atli's Avatar
Moderator
 
Join Date: Nov 2006
Location: Iceland
Posts: 3,701

re: Uploading files into a MySQL database using PHP


Quote:
Originally Posted by Frinavale View Post
Atli this is an awesome article :)
You may want to include a links to the resources that you're using (like the mysqli extension) though :)
Thanks ;-)
Good idea. I've added links to the "Before you start" part, to begin with.
Might be worth adding a separate reference part tho.
  #67  
Old September 13th, 2009, 06:38 PM
Newbie
 
Join Date: Mar 2009
Posts: 6

re: Uploading files into a MySQL database using PHP


Hi Atli,

I did everything following the steps provide to do the upload and download file and it was working fine, but for some reason I tried to download a file it keep giving me the following error message "Adobe Reader could not open file.pdf' because it is either not a support file type or because the file has been damaged." I did download the Adobe Reader 9.0 and still giving me the same error message as I open the file. But for some reason if I open the file without download from the fle list, it does open fine. Any idea what am I doing wrong? Any help will be appreciated.

Thank you in advance.

Xiou
  #68  
Old September 15th, 2009, 01:12 AM
Atli's Avatar
Moderator
 
Join Date: Nov 2006
Location: Iceland
Posts: 3,701

re: Uploading files into a MySQL database using PHP


Hey Xiou.

What browser are you using to test this?
Which versions of PHP, MySQL, and what OS is your server running?

I just tested this on my PC and there were no problems uploading and reading PDF files in any of the major browsers. I'm using Adobe Reader 9.1.

My server specs:
Win7 (x64), Apache 2.2, PHP 5.3, MySQL 5.1

It sounds like your file is being corrupted somewhere on the way tho.
Maybe some sort of charset conversion problem? I can't really say.
  #69  
Old October 19th, 2009, 06:53 PM
Newbie
 
Join Date: May 2009
Posts: 1

re: Uploading files into a MySQL database using PHP


I need a help in how to upload 2 files instead 1? thank you in advance. Any help will be appreciated
  #70  
Old October 19th, 2009, 08:24 PM
Atli's Avatar
Moderator
 
Join Date: Nov 2006
Location: Iceland
Posts: 3,701

re: Uploading files into a MySQL database using PHP


Hey.

To upload more than one file, you add more <input> elements, each with a different name.
Expand|Select|Wrap|Line Numbers
  1. <input type="file" name="uploaded_file_1" /><br />
  2. <input type="file" name="uploaded_file_2" /><br />
  3. <input type="file" name="uploaded_file_N" /><br />
  4.  
And then you grab each file from the $_FILES array using it's name:
Expand|Select|Wrap|Line Numbers
  1. $file1 = $_FILES["uploaded_file_1"];
  2. $file2 = $_FILES["uploaded_file_2"];
  3. $fileN = $_FILES["uploaded_file_N"];
  4.  
And then run each of them through the code that inserts it into the database.
You can make this less repetitive by putting the files into an array and looping through it.

There is also a way to upload them as a array, by using the same name for all the <input> boxes, adding brackets to the end [], but that is not necessary for a static form. (More useful for forms that expand using client-side code.)
Reply


Similar Threads
Thread Thread Starter Forum Replies Last Post
MySQL BLOB data corrupted on retrieval phpmagesh answers 6 December 31st, 2008 02:25 PM
Mysql database in UTF8, PHP shows latin1 (iso-8859-1) alex answers 39 June 27th, 2008 05:15 PM
uploading several docs at once Chris answers 5 August 9th, 2006 10:15 PM
Problem connecting to remote MySQL DB from VB6 Ian Davies answers 4 October 12th, 2005 07:05 PM