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.
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)
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.
Interested people or those having problems should also read here for details:
or here:
This could help in case of problems.
Somehow broken… sorry, I meant:
http://www.thomasweidner.com/flatpress/category/file-transfer/
and http://www.thomasweidner.com/flatpress/2009/04/17/recieving-files-with-zend_form_element_file/
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']="";
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
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
totally useless tutorial!
tttttttttttttaaaaaaaaaanks
:*
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;
}
It’s a good idea to upload the project files you are talking about.