Patrioticcow
Patrioticcow

Reputation: 27048

multi picture upload in zend framework, how to?

i have an issue with uploading multiple files to disk. here is my code.

i have a request with 2 pictures that gets sent to a upload function. the 2 pictures are in a var called $multiUpload

$folderPath = '/var/www/';
if (is_array($multiUpload)){
            $file = array();
            $filename = array();

            foreach($multiUpload as $key=>$val){
                // get the file extension
                $file[] = explode('.',$val);

                // create custom file name
                $filename[] = time().'.'.$file[$key][1];

                //send to the upload function
                $this->uploadToDisk($folderPath, $filename[$key]);

                // sleep 1 sec so that the pic names will be different
                sleep(1);
            }
                 return $filename;

        }


public function uploadToDisk($folderPath, $filename)
{

    $adapter = new Zend_File_Transfer_Adapter_Http();
    $adapter->setDestination($folderPath);
    $adapter->addFilter( 'Rename',array(
            'target' => $folderPath."/".$filename,
            'overwrite' => true
            ) );
    if ($adapter->receive()) {
        $message = "success";
    } else {
        $message = "fail";
    }

    return $message;
}

this will return

Array
(
    [0] => Array
        (
            [0] => 1332977938.jpg
            [1] => 1332977939.jpg
        )

)

but only array[0][0] or 1332977938.jpg will actually get saves to the disk.

Why are they now both get saved? wired

any ideas?

Upvotes: 2

Views: 2032

Answers (1)

drew010
drew010

Reputation: 69957

I suspect the second call to uploadToDisk is returning fail because you can only call Zend_File_Transfer_Adapter_Http::receive() once for each file. Since you are not specifying a file when calling receive, it is receiving all of the files the first time you call uploadToDisk and subsequently is failing with a File Upload Attack error.

Here is some code you can try. This tries to receive each file individually and then save them one at a time with each call to uploadToDisk.

A few notes about the code:

  • The first parameter to uploadToDisk ($val) may need to be changed as I am not sure what the original values are. It should correspond to one of the element names used for the file upload (See Zend_File_Transfer_Adapter_Http::getFileInfo()) for a list of the files.
  • I changed the method for generating a unique filename so you don't have to sleep(1)
  • Zend_File_Transfer_Adapter_Abstract::setDestination() is deprecated and will go away in the future. Instead, just use the Rename filter. When using Rename, setDestination() has no effect.

And here it is...

<?php

$folderPath = '/var/www/';

if (is_array($multiUpload)){
    $filenames = array();

    foreach($multiUpload as $key => $val){
        // get the file extension
        $ext = explode('.', $val);
        $ext = $ext[sizeof($ext) - 1];

        // create custom file name
        do {
            $filename = uniqid(time()) . '.' . $ext;
            $diskPath = $folderPath . $filename;
        } while (file_exists($diskPath));

        $filenames[$key] = $filename;

        //send to the upload function
        // $val is the file to receive, $diskPath is where it will be moved to
        $this->uploadToDisk($val, $diskPath);
    }

    return $filename;
}


public function uploadToDisk($file, $filename)
{
    // create the transfer adapter
    // note that setDestination is deprecated, instead use the Rename filter
    $adapter = new Zend_File_Transfer_Adapter_Http();
    $adapter->addFilter('Rename', array(
            'target'    => $filename,
            'overwrite' => true
    ));

    // try to receive one file
    if ($adapter->receive($file)) {
        $message = "success";
    } else {
        $message = "fail";
    }

    return $message;
}

Upvotes: 3

Related Questions