Reputation: 4491
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.
Upvotes: 6
Views: 2903
Reputation: 1817
This would work - tested!
if( !empty($_FILES['SOME_INPUT_NAME'] ) {
$multimgs = $_FILES['SOME_INPUT_NAME'];
$imgs_arr = array();
// first build into working array
foreach($multimgs as $key => $value) {
foreach($pimgs[$key] as $subkey => $subvalue) {
$imgs_arr[$subkey][$key] = $subvalue;
}
}
}
Then you can loop through $imgs_arr - images array. those would be in a normal,
FILE structure which you can use to upload etc.
Upvotes: 0
Reputation: 463
Another variant of recursive reordering based on clamcrusher's solution from here
function getFixedFilesArray() {
$walker = function ($arr, $fileInfokey, callable $walker) {
$ret = array();
foreach ($arr as $k => $v) {
if (is_array($v)) {
$ret[$k] = $walker($v, $fileInfokey, $walker);
} else {
$ret[$k][$fileInfokey] = $v;
}
}
return $ret;
};
$files = array();
foreach ($_FILES as $name => $values) {
// init for array_merge
if (!isset($files[$name])) {
$files[$name] = array();
}
if (!is_array($values['error'])) {
// normal syntax
$files[$name] = $values;
} else {
// html array feature
foreach ($values as $fileInfoKey => $subArray) {
$files[$name] = array_replace_recursive($files[$name], $walker($subArray, $fileInfoKey, $walker));
}
}
}
return $files;
}
The main difference from the original solution is that I replaced array_merge_recursive with array_replace_recursive so that indexed arrays in a tree will not produce invalid result (array_merge_recursive for indexed arrays adds new indexes instead of merging with existing indexes). I've tested this on several quite difficult situations and it worked as expected
Upvotes: 2
Reputation: 2740
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] => ...
)
[...]
)
)
Upvotes: 4
Reputation: 51
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).
Upvotes: 5
Reputation: 254886
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.
Upvotes: 6