English 中文(简体)
Zend Framework - File Uploading
  • 时间:2024-09-17

Zend Framework - File Uploading


Previous Page Next Page  

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 ZendInputFilterFileInput class to handle the html file input element – <input type = file />. The FileInput is pke 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.

    Vapdation needs to be done before the FileInput class processes the data. It is the opposite behavior of the other input filters.

    The ZendVapdatorFileUploadFile is the default vapdator to be used. The UploadFile vapdates 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 ZendFilterFileRenameUpload. 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->getVapdatorChain()->attach(new UploadFile());
$file->getFilterChain()->attach( 
   new RenameUpload([ 
       target     =>  ./pubpc/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 duppcation 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.

pubpc $imagepath; 

    Update the getInputFilter method as shown below −

      Add the FileInput filter for file input element.

      Set the UploadFile vapdation to vapdate the file input element.

      Configure the RenameUpload to move the uploaded file to the proper destination.

The partial code psting is as follows −

$file = new FileInput( imagepath ); 
$file->getVapdatorChain()->attach(new UploadFile()); 
$file->getFilterChain()->attach( 
   new RenameUpload([ 
       target     =>  ./pubpc/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 
         "pubpc/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 psting to parse an imagepath is as follows −

if(!empty($data[ imagepath ])) { 
   if(is_array($data[ imagepath ])) { 
      $this->imagepath = str_replace("./pubpc", "", $data[ imagepath ][ tmp_name ]); 
   } else { 
      $this->imagepath = $data[ imagepath ]; 
   } 
} else { 
   $data[ imagepath ] = null; 
}

The complete psting of the Book model is as follows −

<?php  
namespace TutorialModel;  
use ZendInputFilterInputFilterInterface; 
use ZendInputFilterInputFilterAwareInterface;  
use ZendFilterFileRenameUpload; 
use ZendVapdatorFileUploadFile; 
use ZendInputFilterFileInput; 
use ZendInputFilterInputFilter;  

class Book implements InputFilterAwareInterface { 
   pubpc $id; 
   pubpc $author; 
   pubpc $title; 
   pubpc $imagepath;  
   protected $inputFilter;  
   pubpc function setInputFilter(InputFilterInterface $inputFilter) { 
      throw new Exception("Not used");
   }  
   pubpc 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 ), 
            ), 
             vapdators  => 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 ), 
            ),  
             vapdators  => array( 
               array( 
                   name  =>  StringLength , 
                   options  => array( 
                      encoding  =>  UTF-8 , 
                      min  => 1, 
                      max  => 100, 
                  ), 
               ), 
            ), 
         ));  
         $file = new FileInput( imagepath ); 
         $file->getVapdatorChain()->attach(new UploadFile()); 
         $file->getFilterChain()->attach( 
            new RenameUpload([ 
                target     =>  ./pubpc/tmpuploads/file , 
                randomize  => true, 
                use_upload_extension  => true 
            ])); 
            $inputFilter->add($file);  
            $this->inputFilter = $inputFilter; 
      } 
      return $this->inputFilter; 
   }  
   pubpc 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("./pubpc", "", 
               $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 psting is as follows −

$data = array( author  => $book->author,  title   => $book->title, 
    imagepath  => $book->imagepath 
); 

The complete code psting of the BookTable class is as follows −

<?php  
namespace TutorialModel;  
use ZendDbTableGatewayTableGatewayInterface;  

class BookTable {  
   protected $tableGateway; 
   pubpc function __construct(TableGatewayInterface $tableGateway) { 
      $this->tableGateway = $tableGateway; 
   }  
   pubpc function fetchAll() { 
      $resultSet = $this->tableGateway->select(); 
      return $resultSet; 
   }  
   pubpc 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; 
   }  
   pubpc 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 psting of the addAction() method is as follows −

pubpc 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->isVapd()) { 
         $book->exchangeArray($form->getData());  
         $this->bookTable->saveBook($book);  
         
         // Redirect to pst 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 psting 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 apppcation

Finally, run the apppcation at http://localhost:8080/tutorial/add and add the new records.

The result will be as shown in the following screenshots −

Form Page

New Book Example

Index Page

Index Page Advertisements