Zend Framework: Uploading and renaming multiple files

16 Apr

Waf!, I used Zend_File component about two month back. Did I test that before writing an article, yes surely, I did. But what, I did that for only one file, though I was intending to upload multiple files. I didn’t check my directory, however no exception was thrown and no error message jumped out. I thought that I have successfully completed my job and now its time to write an article to help those needed.

Sorry gays, I was completely wrong. The example, if you have used upload only one file.

A person once post his/her comments that It won’t upload multiple files, however I was having enough time to test my code again.

But today I decided that I will need to do something and make this example working as I was intending to make it. So I’m here to tell you how to upload multiple files.

An addition to uploading multiple files, I’d show you how to rename files.

In the first example I’d tell you how to upload multiple files and then in the second example I’d tell you how to rename them if you like.

So let have a look.

First of all, create your form as

<?php

class CustomForm extends Zend_Dojo_Form

{

public function init()

{

$this->setMethod(‘post’);

$this->setAttrib(‘enctype’, ‘multipart/form-data’);

$ this ->addElement(‘file’,’file1′,array(‘label’=>’File1’));

$ this ->addElement(‘file’,’file2′,array(‘label’=>’File1’));

$ this ->addElement(‘submit’,’submit’);

}

}

In the code above we have done thing more than creating a form, setting its method, enctype, add two file elements and submit button.

Now in controller write

$form = new CustomForm();

$this->view->form = $form;

if($this->getRequest()->isPost()) {

if  ($form->isValid($_POST)) {

$adapter=new Zend_File_Transfer_Adapter_Http();

$uploadDir=dirname(__File__);

$adapter->setDestination($uploadDir);

foreach ($adapter->getFileInfo() as $info) {

if(!$adapter->receive($info[‘name’])){

$this->view->msg=$adapter->getMessages();

return;

}

}

}

}

Okay, the entire logic is written in the above code. First we create our own custom form instance and assign it to the view template. Then we check if the form is submitted by using isPost() method. In the next condition we check if the form is validly posted. I yes, we create an adapter. You will need to create transfer adapter.

In the next line we set our destination directory, directory we want to upload our files.

Foreach loop is compulsory for uploading multiple files, if you want to upload single file then there is no need to use this loop.

After the foreach loop we call receive method giving name of each file.

That’s it, we have done.

Renaming files will take some extra code. Make the following changes in your controller.

$form = new CustomForm();

$this->view->form = $form;

if($this->getRequest()->isPost()) {

if  ($form->isValid($_POST)) {

$adapter=new Zend_File_Transfer_Adapter_Http();

$uploadDir=dirname(__File__);

$adapter->setDestination($uploadDir);

$i= 1;

foreach ($adapter->getFileInfo() as $info) {

$ext = $this->_findexts($info[‘name’]);

$fileName = ‘file’.$i.time().”.”.$ext;

$i++;

$adapter->addFilter(‘Rename’,

array(‘target’ => $uploadDir.DIRECTORY_SEPARATOR.$fileName,

‘overwrite’ => true));

if(!$adapter->receive($info[‘name’])){

$this->view->msg=$adapter->getMessages();

return;

}

}

}

}

protected function _findexts($filename)

{

$filename = strtolower($filename) ;

$exts = split(“[/\\.]”, $filename) ;

$n = count($exts)-1;

$exts = $exts[$n];

return $exts;

}

The only change made are in bold. We have defined a protected method for find the extension.

We call this function to get the file extension, which is concatenated with the name of the file, we are building.

The real part is performed by

$adapter->addFilter(‘Rename’,

array(‘target’ => $uploadDir.DIRECTORY_SEPARATOR.$fileName,

‘overwrite’ => true));

Here if don’t give “overwrite”, zend will generate error if file with the same name already exist.

11 Responses to “Zend Framework: Uploading and renaming multiple files”

  1. thomas April 22, 2009 at 12:18 pm #

    1.) Ressource intensive… you should better use $form->file1->getTransferAdapter() instead of creating another instance.

    2.) Setting the upload location to the directory of the actual script is a security and organisation problem… you should always use a fixed sorage path (f.e. /var/www/upload/temp)

    3.) You should not use getFileInfo to get the filename as this information can change after the file has been received. See getValues() or setting a filter. Use getFileName() instead. It always returns the correct name.

    4.) Calling receive WITHOUT a set file will receive ALL FILES… a foreach as shown in your first example, is completly useless (except setting a different path for each file)

  2. Faheem Abbas April 22, 2009 at 12:36 pm #

    Well, this article wasn’t written keeping security issues in mind, better to keep in mind while working on actual application. I faced lot of issues using File component until new ZF version released specially in renaming it. I used the method above and it worked for me. As lot of other developer around are having same issues I faced, so I write what I’ve done in my application.
    I do keep in mind security issues while developing application and hopefully other developers will be doing the same.
    Anyhow thanks for your valuable suggestions.

  3. thomas April 22, 2009 at 12:53 pm #

    Interested people or those having problems should also read here for details:

    or here:

    This could help in case of problems.😉

  4. Vova August 1, 2009 at 6:23 pm #

    My function for ext…

    $file_name=basename($_FILES['rfile']['name']);
    $c=strrpos($file_name,'.');
    if($c) $data['extension']=strtolower(substr($file_name,$c+1)); //ext
    else $data['extension']="";

  5. jake March 12, 2010 at 10:29 am #

    public function checkcpwd($id,$opassword)
    {
    $id = (int)$id;
    $data = array(‘member_id’=>$id, ‘password’=>$opassword);
    $row = $this->fetchRow($data,’member_id=’.(int)$id , ‘password=’.$opassword );
    }
    ***********
    iam calling this function to fetch the row from the database where the table contains the given id and password…….
    its nott working plz help me

  6. jake March 16, 2010 at 11:36 am #

    how can we move the files from tmp location to our required destination in zend frame work 1.10
    plz give me tdhe solution for this

    thanks in advance

  7. sean June 14, 2010 at 3:25 am #

    totally useless tutorial!

  8. HamidReza June 23, 2010 at 9:24 am #

    tttttttttttttaaaaaaaaaanks😀 :*

  9. Shamun September 29, 2010 at 9:58 pm #

    Anyway ZF users. Why not use this?

    #
    # ZF/application/models/Db.php
    #
    class Application_Model_Db
    {

    /* Call me when you need me!! example: Application_Model_Db::mvUploadFile(); */
    /* @return filename.html */
    /* */
    public function mvUploadFile()
    {
    # its simploy a $_FILES !!
    $fname = basename( $_FILES[‘attachment’][‘name’]);
    $_fname = strtolower (end(explode(‘.’,$fname) ) );
    Zend_Debug::dump( $_FILES ); // go deep inside !!!

    # allow or not!
    switch($_fname)
    {
    case ($_fname == ‘jpg’ ||
    $_fname == ‘jpeg’ ||
    $_fname == ‘gif’ ||
    $_fname == ‘bmp’ ||
    $_fname == ‘png’ ||
    $_fname == ‘html’ ||
    $_fname == ‘pdf’ ||
    $_fname == ‘doc’ ||
    $_fname == ‘docx’ ||
    $_fname == ‘xls’
    ):
    $target_path = APPLICATION_PATH . “/../public/files/textual_translation_attachment/”;
    #chmod($target_path , 0777);

    $target_path = $target_path . basename( $_FILES[‘attachment’][‘name’]);

    if(move_uploaded_file($_FILES[‘attachment’][‘tmp_name’], $target_path)) {
    #echo “The file “. basename( $_FILES[‘file’][‘name’]). ” has been uploaded”;
    #$_sql = “insert into a (huis,image) values (‘$_app’,’$_file’)”;
    #send the file name only …..
    #echo $fname ;
    }else{
    #echo “error “;
    }
    break;
    }

    return $fname;

    }

  10. john December 1, 2010 at 6:27 pm #

    It’s a good idea to upload the project files you are talking about.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: