Like always I am sharing new things I learn here on my blog. I was recently working on a requirement for a LAMP stack web application reporting dashboard in which I needed to store – and eventually – retrieve a .pdf file. I have read in several places (this fantastic book is a great resource) that a viable option is storing images or documents (.pdf in this case) in the actual database table as opposed to on the server file system. MySQL has the BLOB
datatype that can be used to store files such as .pdf, .jpg, .txt, and the like. In this blog post, I cover how I accomplished uploading and storing the actual .pdf file in a BLOB
column in MySQL using PHP. Any corrections, tips, pointers, and recommendations for best practices are always welcome. We all learn as we go!!!
Self-Promotion:
If you enjoy the content written here, by all means, share this blog and your favorite post(s) with others who may benefit from or like it as well. Since coffee is my favorite drink, you can even buy me one if you would like!
I am using a table named ‘project_pdf’ with 3 columns (see accompanying screenshot) to store the data:
- ‘id’: type
INTEGER
- ‘project_name’: type
TEXT
- ‘pdf_doc’: type
BLOB
With the below simple HTML web form
, we can collect the ‘project_name’ and enable the .pdf file attachment upload:
Below is the HTML source code for the above web form
:
<title>Upload PDF</title>
</p><h4 class=“text-center” style=“margin-top: 100px;”>Upload A PDF To The Database</h4>
<div class=“d-flex justify-content-center align-self-center” style=“margin-top: 115px;”>
<form action=“submit.php” method=“POST” accept-charset=“utf-8” enctype=“multipart/form-data”>
<div class=“formgroup container-fluid”>
<label for=“project_name”>Project Name</label>
<input type=“text” name=“project_name”/>
</div>
<div class=“formgroup container-fluid”>
<input type=“file” name=“pdf_file” accept=“.pdf”/>
<input type=“hidden” name=“MAX_FILE_SIZE” value=“67108864”/> <!–64 MB‘s worth in bytes–>
</div>
<div class=”formgroup container-fluid”>
<label for=”submit”>Submit To Database</label><br />
<input type=”submit” name=”submit”/>
</div>
</form>
</div>
<script src=”https://code.jquery.com/jquery-3.5.1.slim.min.js” integrity=”sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj” crossorigin=”anonymous”></script>
<script src=”https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js” integrity=”sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN” crossorigin=”anonymous”></script>
<script src=”https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js” integrity=”sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV” crossorigin=”anonymous”></script>
Looking at the code…
We will use this PHP code stored in a script submit.php
– which is the form
action
– along with some best practices utilizing if/else
conditional blocks and wrapping all of the database operations in a try/catch
block to complete the .pdf INSERT
in the MySQL BLOB
column:
if (isset($_POST[‘submit’]) && !empty($_FILES[‘pdf_file’][‘name’])) {
//a $_FILES ‘error’ value of zero means success. Anything else and something wrong with attached file.
if ($_FILES[‘pdf_file’][‘error’] != 0) {
echo ‘Something wrong with the file.’;
} else { //pdf file uploaded okay.
//project_name supplied from the form field
$project_name = htmlspecialchars($_POST[‘project_name’]);
//attached pdf file information
$file_name = $_FILES[‘pdf_file’][‘name’];
$file_tmp = $_FILES[‘pdf_file’][‘tmp_name’];
if ($pdf_blob = fopen($file_tmp, “rb”)) {
try {
include __DIR__.“/includes/DatabaseConnection.php”;
$insert_sql = “INSERT INTO `project_pdf` (`project_name`, `pdf_doc`)
VALUES(:project_name, :pdf_doc);”;
$stmt = $pdo->prepare($insert_sql);
$stmt->bindParam(‘:project_name’, $project_name);
$stmt->bindParam(‘:pdf_doc’, $pdf_blob, PDO::PARAM_LOB);
if ($stmt->execute() === FALSE) {
echo ‘Could not save information to the database’;
} else {
echo ‘Information saved’;
}
} catch (PDOException $e) {
echo ‘Database Error ‘. $e->getMessage(). ‘ in ‘. $e->getFile().
‘: ‘. $e->getLine();
}
} else {
//fopen() was not successful in opening the .pdf file for reading.
echo ‘Could not open the attached pdf file’;
}
}
} else {
//submit button was not clicked. No direct script navigation.
header(‘Location: choose_file.php’);
}
Verify the button is clicked and a file is attached
The first if/else
block verifies that the ‘submit’ button from the form
has been clicked and that the ‘pdf_file’ field has an attachment using the PHP functions isset()
and empty()
(the converse of truth by negating with the not ! operator for the empty()
function):
1
|
isset($_POST[‘submit’]) && !empty($_FILES[‘pdf_file’][‘name’]))
|
Tip: More validation can be implemented here to verify the file type is an actual .pdf since that file type is what we are expecting to store in the database.
Informational: Visit the official PHP online documentation for more information on isset() and empty().
Check PHP $_FILES array for errors
The $_FILES
array
provides several related error codes for file attachments. A value of 0 (zero) means everything is okay with the file and it is successfully uploaded. In this particular if/else
, block if that value is not 0 (zero), then we echo
in the browser that something is wrong with the file upload:
1
|
$_FILES[‘pdf_file’][‘error’] != 0
|
Related: See the official PHP online documentation for more information on file upload errors.
PHP $_POST and $_FILES Data
The $_POST
associative array has the value for the ‘project_name’ input
field captured in the form
and sent through the HTTP POST method.
Likewise, the $_FILES
associative array has several values for a file or attachment. I am assigning 2 of them to variables, but using only one – ['tmp_name']
– in the subsequent code:
-
['name']
– The actual file name from the client. (Could be used in a file name column if needed -
['tmp_name']
– Temporary file name of the uploaded file as stored on the server.
1
2 3 |
$project_name = htmlspecialchars($_POST[‘project_name’]);
$file_name = $_FILES[‘pdf_file’][‘name’]; $file_tmp = $_FILES[‘pdf_file’][‘tmp_name’]; |
Related: Read more about POST upload methods in the official online PHP documentation.
Read in .pdf binary data and prepare to store in MySQL BLOB column with PHP
The call to fopen()
reads in the file in binary format ("rb"
) into a ‘$pdf_blob’ variable. If fopen()
cannot open the file, this if/else
block echo
‘s the message in the else
block to the browser:
1
|
$pdf_blob = fopen($file_tmp, “rb”)
|
MySQL database connection and prepared statements
Finally, we look at the entire try/catch
block.
I have all database connection information stored in a separate file named DatabaseConnection.php
and include it in the script at this point using the include
directive.
Since we are introducing user-supplied input from the web form
into the database, we use prepared statements leveraging the PHP PDO methods:
prepare()
bindParam()
execute()
INSERT .pdf file into MySQL BLOB column with PHP
If the call to execute()
is not successful, we echo
a message to the browser that the information could not be saved. Otherwise, the data is successfully inserted and we echo
‘Information saved’:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
try {
include __DIR__.“/includes/DatabaseConnection.php”; $insert_sql = “INSERT INTO `project_pdf` (`project_name`, `pdf_doc`) $stmt = $pdo->prepare($insert_sql); if ($stmt->execute() === FALSE) { |
Note: It is generally not a good practice to echo
any sort of database error information to the browser. Errors should be written to a log file instead. However, for the purpose of this blog post as a learning experience, I echo
out any exceptions that may arise in the catch
block.
Using the form to store .pdf in MySQL BLOB column with PHP
Let’s try out the form and PHP code to verify the upload works. Here is a simple sample .pdf file I created for a demo run:
See this screenshot in which I fill in the ‘project name’ field with a generic ‘First Project’ name and attach the SimplePDF.pdf file:
Upon clicking the ‘Submit’ button, the information is successfully stored in the database and the success message is displayed in the browser:
Here is the data saved in the MySQL database table from the successful upload via our web form and the PHP code:
It works!!!
In the next blog post, I will cover how to retrieve the .pdf file from the database and display it in the browser. If you see anything in the code that I can improve on or any mistake, please let me know via the comments section below.
Additional PHP/MySQL Reading
Be sure and visit these other blog posts I have written on PHP and MySQL:
- PHP PDO lastInsertId() method with examples in MySQL
- Beginning Perspective on PHP Arrays
- Sorting associative arrays in PHP with array_multisort() – New learning
- Dynamic HTML drop-down with PHP and MySQL
Like what you have read? See anything incorrect? Please comment below and thanks for reading!!!
A Call To Action!
Thank you for taking the time to read this post. I truly hope you discovered something interesting and enlightening. Please share your findings here, with someone else you know who would get the same value out of it as well.
Visit the Portfolio-Projects page to see blog post/technical writing I have completed for clients.
To receive email notifications (Never Spam) from this blog (“Digital Owl’s Prose”) for the latest blog posts as they are published, please subscribe (of your own volition) by clicking the ‘Click To Subscribe!’ button in the sidebar on the homepage! (Feel free at any time to review the Digital Owl’s Prose Privacy Policy Page for any questions you may have about: email updates, opt-in, opt-out, contact forms, etc…)
Be sure and visit the “Best Of” page for a collection of my best blog posts.
Josh Otwell has a passion to study and grow as a SQL Developer and blogger. Other favorite activities find him with his nose buried in a good book, article, or the Linux command line. Among those, he shares a love of tabletop RPG games, reading fantasy novels, and spending time with his wife and two daughters.
Disclaimer: The examples presented in this post are hypothetical ideas of how to achieve similar types of results. They are not the utmost best solution(s). The majority, if not all, of the examples provided, is performed on a personal development/learning workstation-environment and should not be considered production quality or ready. Your particular goals and needs may vary. Use those practices that best benefit your needs and goals. Opinions are my own.
The post Use MySQL BLOB column with PHP to store .pdf file appeared first on Digital Owl’s Prose.