Managing File Uploads with the Zend Framework

Introduction

Whether managing videos to YouTube, sharing PowerPoint presentations on SlideShare, or using the open source e-commerce platform Magento to update your online store's product images, chances are you've become well acquainted with the Web-based mechanism used to upload files to the Web. But how does this mechanism actually work? What process results in the file being transferred from your computer to the remote server? In this tutorial I'll show you how to create your own file upload mechanism using the popular Zend Framework, which makes accepting, validating, and processing uploaded files a walk in the park.

Configuring PHP to Handle File Uploads

PHP is natively capable of performing the task of managing file uploads submitted via a Web form, however whether you're using standard PHP code or the Zend Framework to manage your uploads, you'll probably want to take a moment to examine several of the configuration directives which directly impact PHP's capability to do so:

upload_max_filesize: This directive defines the maximum allowable size of an uploaded file. By default this directive is set to 2 Megabytes.

upload_tmp_dir: This directive defines the temporary directory used by PHP to store uploaded files before they are moved to their final destination as determined by the developer. By default this directive is not assigned a value, meaning PHP will use the system's default (for instance, /tmp on many Linux distributions)

post_max_size:

max_execution_time: Although not strictly related to file uploads, this directive nonethless plays an important role in PHP's file upload capabilities because it defines the amount of time a PHP script will execute. Because particularly large files may require significant periods of time to transfer to the file server, you might consider increasing this directive's default of 30 seconds to 60 or even 90 seconds.

Creating this form is almost identical to other forms you've created in the past, with a few slight yet important changes. The HTML used to create this form is presented in Listing 1. As is typical with the Zend Framework, I've placed this form in a view named upload.phtml, which forms part of an action named upload located in a controller named admin.

In particular you should take note of two important bits of code found in this form:

enctype="multipart/form-data": This form attribute should be used when you send large amounts of binary data via a Web form. Because files such as spreadsheets and videos do indeed contain large amounts of binary data, be sure to include this attribute when creating a file upload form.

<input type="file" name="video-upload" size="40" />: This form element will create the form mechanism allowing users to search their local file system for a file they wish to upload. When the submit button is pressed, this file will be uploaded and sent to the script as identified by the form action (in this case, upload.php) for further processing.

As the second bullet point states, the file will be uploaded to the script identified by the form's action attribute. However unless the script actually does something with the file, the data will be lost. In the next section you'll learn how to use the Zend Framework's Zend_File_Transfer component to process this uploaded file.

Introducing the Zend_File_Transfer Component

Like so many of the other powerful components made available through the Zend Framework, the Zend_File_Transfer component is intended to make your life much easier when it comes to the task of uploading files from a user's computer to a Web server. In actuality, this component is much more flexible than merely handling uploads; it can also be used to transfer files using protocols such as FTP and WebDAV, however for the purposes of this tutorial we'll stick to its initially stated purpose. Let's begin by creating the simplest process possible in the upload action which is nonetheless capable of accepting and processing an uploaded file:

I've added line numbers to the action, so the important bits of the code can be easily referenced in the summary that follows:

Line 04 determines whether a POST request has been submitted to the action. This is useful for creating actions which are responsible for both presenting the form to the user, and acting upon any data submitted through the form.

Line 06 invokes the Zend_File_Transfer class component, using specifically the HTTP adapter which is capable of processing data submitted through a Web form.

Line 08 sets the final destination of the uploaded file. While you're free to pass a path directly into this method, I find it far more convenient to store the path in the application.ini file, and then retrieve the configuration parameter as needed. This allows me to easily change that path destination as desired, a convenience which is particularly appreciated when moving code from my development to production servers.

Line 10 is responsible for accepting the file and moving it to the desired destination.

Believe it or not, these sixteen lines are capable of accepting and moving an uploaded file to the desired location on your server! However, at this point your alarm bells should be sounding off, because the script is missing a crucial step which should be part of any process involved in accepting user input. That's right, this script allows the user to upload any file he pleases, which is almost certainly a recipe for disaster! Thankfully, the Zend_File_Transfer component is packed with data validation methods capable of examining practically every conceivable aspect of the file upload process.