
- Zend Framework Tutorial
- Zend Framework - Home
- Zend Framework - Introduction
- Zend Framework - Installation
- Skeleton Application
- Zend Framework - MVC Architecture
- Zend Framework - Concepts
- Zend Framework - Service Manager
- Zend Framework - Event Manager
- Zend Framework - Module System
- Application Structure
- Zend Framework - Creating Module
- Zend Framework - Controllers
- Zend Framework - Routing
- Zend Framework - View Layer
- Zend Framework - Layout
- Models & Database
- Different Databases
- Forms & Validation
- Zend Framework - File Uploading
- Zend Framework - Ajax
- Cookie Management
- Session Management
- Zend Framework - Authentication
- Email Management
- Zend Framework - Unit Testing
- Zend Framework - Error Handling
- Zend Framework - Working Example
- Zend Framework Useful Resources
- Zend Framework - Quick Guide
- Zend Framework - Useful Resources
- Zend Framework - Discussion
Zend Framework - File Uploading
File uploading is one of the main concept in form programming. Zend framework provides all the necessary items to upload files through the zend-form and the zend-inputfilter component.
FileInput Class
The zend-inputfilter component provides Zend\InputFilter\FileInput class to handle the html file input element – <input type = 'file' />. The FileInput is like the other input filters with a few exceptions. They are as follows −
Since PHP saves the uploaded file details in $_FILES global array, the FileInput gathers the uploaded file information through $_FILES only.
Validation needs to be done before the FileInput class processes the data. It is the opposite behavior of the other input filters.
The Zend\Validator\File\UploadFile is the default validator to be used. The UploadFile validates the file input details.
To add a file upload type in a form, we need to use input type File. The partial code is as follows −
$form->add(array( 'name' => 'imagepath', 'type' => 'File', 'options' => array('label' => 'Picture',), ));
Another class used in file uploading is Zend\Filter\File\RenameUpload. The RenameUpload is used to move the uploaded file to our desired location. The partial class to use file filter is as follows −
$file = new FileInput('imagepath'); $file->getValidatorChain()->attach(new UploadFile()); $file->getFilterChain()->attach( new RenameUpload([ 'target' => './public/tmpuploads/file', 'randomize' => true, 'use_upload_extension' => true ])); $inputFilter->add($file);
Here, the options of RenameUpload are as follows −
target − The destination path of the uploaded file.
randomize − Add a random string to prevent duplication of the uploaded file.
use_upload_extension − Append the file extension to the uploaded file to the target.
File Upload – Working Example
Let us modify the tutorial module and include a picture upload feature.
Modify the database table
Let us add the imagepath column to the book table by executing the following SQL command −
ALTER TABLE `book` ADD `imagepath` VARCHAR(255) NOT NULL AFTER 'imagepath';
Update BookForm.php
Add the file input element to upload a picture in the book form – myapp/module/Tutorial/src/Model/BookForm.php.
Include the following code in the __constructmethod of the BookForm class.
$this->add(array( 'name' => 'imagepath', 'type' => 'File', 'options' => array ('label' => 'Picture',), ));
Update Book.php
Do the following changes in the Book class – myapp/module/Tutorial/src/Model/Book.php.
Add a new property imagepath for the picture.
public $imagepath;
Update the getInputFilter method as shown below −
Add the FileInput filter for file input element.
Set the UploadFile validation to validate the file input element.
Configure the RenameUpload to move the uploaded file to the proper destination.
The partial code listing is as follows −
$file = new FileInput('imagepath'); $file->getValidatorChain()->attach(new UploadFile()); $file->getFilterChain()->attach( new RenameUpload([ 'target' => './public/tmpuploads/file', 'randomize' => true, 'use_upload_extension' => true ])); $inputFilter->add($file);
Update the exchangeArray method to include the imagepath property. The imagepath may come from a form or a database. If the imagepath comes from a form, the format will be an array with the following specification −
array(1) { ["imagepath"] => array(5) { ["name"] => string "myimage.png" ["type"] => string "image/png" ["tmp_name"] => string "public/tmpuploads/file_<random_string>.<image_ext>" ["error"] => int <error_number> ["size"] => int <size> } }
If the imagepath comes from a database, it will be a simple string. The partial code listing to parse an imagepath is as follows −
if(!empty($data['imagepath'])) { if(is_array($data['imagepath'])) { $this->imagepath = str_replace("./public", "", $data['imagepath']['tmp_name']); } else { $this->imagepath = $data['imagepath']; } } else { $data['imagepath'] = null; }
The complete listing of the Book model is as follows −
<?php namespace Tutorial\Model; use Zend\InputFilter\InputFilterInterface; use Zend\InputFilter\InputFilterAwareInterface; use Zend\Filter\File\RenameUpload; use Zend\Validator\File\UploadFile; use Zend\InputFilter\FileInput; use Zend\InputFilter\InputFilter; class Book implements InputFilterAwareInterface { public $id; public $author; public $title; public $imagepath; protected $inputFilter; public function setInputFilter(InputFilterInterface $inputFilter) { throw new \Exception("Not used"); } public function getInputFilter() { if (!$this->inputFilter) { $inputFilter = new InputFilter(); $inputFilter->add(array( 'name' => 'id', 'required' => true, 'filters' => array( array('name' => 'Int'), ), )); $inputFilter->add(array( 'name' => 'author', 'required' => true, 'filters' => array( array('name' => 'StripTags'), array('name' => 'StringTrim'), ), 'validators' => array( array( 'name' => 'StringLength', 'options' => array( 'encoding' => 'UTF-8', 'min' => 1, 'max' => 100, ), ), ), )); $inputFilter->add(array( 'name' => 'title', 'required' => true, 'filters' => array( array('name' => 'StripTags'), array('name' => 'StringTrim'), ), 'validators' => array( array( 'name' => 'StringLength', 'options' => array( 'encoding' => 'UTF-8', 'min' => 1, 'max' => 100, ), ), ), )); $file = new FileInput('imagepath'); $file->getValidatorChain()->attach(new UploadFile()); $file->getFilterChain()->attach( new RenameUpload([ 'target' => './public/tmpuploads/file', 'randomize' => true, 'use_upload_extension' => true ])); $inputFilter->add($file); $this->inputFilter = $inputFilter; } return $this->inputFilter; } public function exchangeArray($data) { $this->id = (!empty($data['id'])) ? $data['id'] : null; $this->author = (!empty($data['author'])) ? $data['author'] : null; $this->title = (!empty($data['title'])) ? $data['title'] : null; if(!empty($data['imagepath'])) { if(is_array($data['imagepath'])) { $this->imagepath = str_replace("./public", "", $data['imagepath']['tmp_name']); } else { $this->imagepath = $data['imagepath']; } } else { $data['imagepath'] = null; } } }
Update BookTable.php
We have updated BookForm and the Book model. Now, we update the BookTable and modify the saveBook method. This is enough to include the imagepath entry in the data array, $data.
The partial code listing is as follows −
$data = array('author' => $book->author, 'title' => $book->title, 'imagepath' => $book->imagepath );
The complete code listing of the BookTable class is as follows −
<?php namespace Tutorial\Model; use Zend\Db\TableGateway\TableGatewayInterface; class BookTable { protected $tableGateway; public function __construct(TableGatewayInterface $tableGateway) { $this->tableGateway = $tableGateway; } public function fetchAll() { $resultSet = $this->tableGateway->select(); return $resultSet; } public function getBook($id) { $id = (int) $id; $rowset = $this->tableGateway->select(array('id' => $id)); $row = $rowset->current(); if (!$row) { throw new \Exception("Could not find row $id"); } return $row; } public function saveBook(Book $book) { $data = array ( 'author' => $book->author, 'title' => $book->title, 'imagepath' => $book->imagepath ); $id = (int) $book->id; if ($id == 0) { $this->tableGateway->insert($data); } else { if ($this->getBook($id)) { $this->tableGateway->update($data, array('id' => $id)); } else { throw new \Exception('Book id does not exist'); } } } }
Update addAction in the TutorialController.php: File upload information will be available in the $_FILES global array and it can be accessed using the Request's getFiles() method. So, merge both posted data and file upload information as shown below.
$post = array_merge_recursive( $request->getPost()->toArray(), $request->getFiles()->toArray() );
The complete listing of the addAction() method is as follows −
public function addAction() { $form = new BookForm(); $form->get('submit')->setValue('Add'); $request = $this->getRequest(); if ($request->isPost()) { $book = new Book(); $form->setInputFilter($book->getInputFilter()); $post = array_merge_recursive( $request->getPost()->toArray(), $request->getFiles()->toArray() ); $form->setData($post); if ($form->isValid()) { $book->exchangeArray($form->getData()); $this->bookTable->saveBook($book); // Redirect to list of Tutorial return $this->redirect()->toRoute('tutorial'); } } return array('form' => $form); }
Update View of the add.phtml
Finally, change the “add.phtml” and include the imagepath file input element as shown below −
echo $this->formRow($form->get('imagepath'))."<br>";
The complete listing is as follows −
<?php $title = 'Add new Book'; $this->headTitle($title); ?> <h1><?php echo $this->escapeHtml($title); ?></h1> <?php if(!empty($form)) { $form->setAttribute('action', $this->url('tutorial', array('action' => 'add'))); $form->prepare(); echo $this->form()->openTag($form); echo $this->formHidden($form->get('id')); echo $this->formRow($form->get('author'))."<br>"; echo $this->formRow($form->get('title'))."<br>"; echo $this->formRow($form->get('imagepath'))."<br>"; echo $this->formSubmit($form->get('submit')); echo $this->form()->closeTag(); }
Run the application
Finally, run the application at http://localhost:8080/tutorial/add and add the new records.
The result will be as shown in the following screenshots −
Form Page

Index Page
