Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Processing multi-dimensional $_FILES array

I have the following $_FILES array past through for processing from a support form

Array
(
    [file] => Array
        (
            [name] => Array
                (
                    [0] => Test.jpg
                    [1] => Test.doc
                    [2] => Test.php
                    [3] => 
                )

            [type] => Array
                (
                    [0] => image/jpeg
                    [1] => image/jpeg
                    [2] => image/jpeg
                    [3] => 
                )

            [tmp_name] => Array
                (
                    [0] => /tmp/phpCO0vSD
                    [1] => /tmp/phpEFpp3Q
                    [2] => /tmp/phpwN4Iwc
                    [3] => 
                )

            [error] => Array
                (
                    [0] => 0
                    [1] => 0
                    [2] => 0
                    [3] => 4
                )

            [size] => Array
                (
                    [0] => 1305787
                    [1] => 339773
                    [2] => 480098
                    [3] => 0
                )

        )

)

My main problem is understanding the logic required in order to process the array, check each file is valid (which I already have a list of valid extensions) then rename and store the file appropriately.

The solutions on Google and SO are both rather complex for my simple requirements.

like image 706
lethalMango Avatar asked Sep 18 '11 22:09

lethalMango


3 Answers

Here is how you would traverse your array:

foreach ($_FILES['file']['name'] as $key => $name) {
    echo $name;
    echo $_FILES['file']['type'][$key];
    echo $_FILES['file']['tmp_name'][$key];
}

Having this loop you can do what you want easily.

like image 58
zerkms Avatar answered Oct 10 '22 05:10

zerkms


I love foreach() so much, I always go with this...

$files = array();
foreach ($_FILES['files']['name'] as $num_key => $dummy) {
    foreach ($_FILES['files'] as $txt_key => $dummy) {
        $files[$num_key][$txt_key] = $_FILES['files'][$txt_key][$num_key];
    }
}

...and then I use foreach($files as $file) again to work with data nicely. :)

Of course that answer from zerkms is faster, but this is general aproach to reorder array logic for any case - you have to walk it twice (x*y).

like image 20
seoguru Avatar answered Oct 10 '22 05:10

seoguru


Here is a more general solution to seoguru's answer. It works with file input fields whose name contains any level of nested arrays, for example file, file[] (the case for this question), file[english], file[english][], etc.

function rearrangeUploadArray(array $array) {
   if(!is_array(reset($array)))
      return $array;

   $rearranged = [];
   foreach($array as $property => $values)
      foreach($values as $key => $value)
         $rearranged[$key][$property] = $value;

   foreach($rearranged as &$value)
      $value = rearrangeUploadArray($value);

   return $rearranged;
}

I realize that this answer is more complicated than it has to be for this question, but maybe it can be useful for someone sometime. An example use case is a localized upload form, where multiple files can be uploaded for different languages. Then it would make sense to have one file input field for each language, named for example file[english][], file[german][], file[spanish][], etc. rearrangeUploadArray($_FILES['file']) will then return an array on the form

Array
(
    [english] => Array
        (
            [0] => Array
                (
                    [name] => ...
                    [type] => ...
                    [tmp_name] => ...
                    [error] => ...
                    [size] => ...
                )

            [1] => Array
                (
                    [name] => ...
                    [type] => ...
                    [tmp_name] => ...
                    [error] => ...
                    [size] => ...
                )

            [...]
        )
    [german] => Array
        (
            [0] => Array
                (
                    [name] => ...
                    [type] => ...
                    [tmp_name] => ...
                    [error] => ...
                    [size] => ...
                )

            [...]
        )
    [spanish] => Array
        (
            [0] => Array
                (
                    [name] => ...
                    [type] => ...
                    [tmp_name] => ...
                    [error] => ...
                    [size] => ...
                )

            [...]
        )
)
like image 31
Magnar Myrtveit Avatar answered Oct 10 '22 05:10

Magnar Myrtveit