At work I've been dealing with some complex forms (publish pages of Symphony) that contain multiple image upload fields. I need a way to quickly merge $_FILES with $_POST, unfortunately you cannot simply merge the two with array_merge because they don't follow the same structure.
Basically if you have $_POST[a][b] it would be $_FILES[a][*][b]. Replace * with one of name, type, tmp_name, error or size.
The content of the $_FILES array as standard:
array
'image-a' => array
'name' => string '' (length=0)
'type' => string '' (length=0)
'tmp_name' => string '' (length=0)
'error' => int 4
'size' => int 0
'image-b' => array
'name' => string '' (length=0)
'type' => string '' (length=0)
'tmp_name' => string '' (length=0)
'error' => int 4
'size' => int 0
'image' => array
'name' => array
'sub' => array
'c' => string '' (length=0)
'type' => array
'sub' => array
'c' => string '' (length=0)
'tmp_name' => array
'sub' => array
'c' => string '' (length=0)
'error' => array
'sub' => array
'c' => int 4
'size' => array
'sub' => array
'c' => int 0
And the desired array after merging with $_POST:
array
'MAX_FILE_SIZE' => string '5242880' (length=7)
'image-a' => array
'name' => string '' (length=0)
'type' => string '' (length=0)
'tmp_name' => string '' (length=0)
'error' => int 4
'size' => int 0
'image-b' => array
'name' => string '' (length=0)
'type' => string '' (length=0)
'tmp_name' => string '' (length=0)
'error' => int 4
'size' => int 0
'image' => array
'sub' => array
'c' => array
'name' => string '' (length=0)
'type' => string '' (length=0)
'tmp_name' => string '' (length=0)
'error' => int 4
'size' => int 0
This is the solution I came up with, calling get_file_post_data returns the merged array:
<?php
if (!empty($_POST)) {
header('content-type: text/plain');
function merge_file_post_data($type, $file, &$post) {
foreach ($file as $key => $value) {
if (!isset($post[$key])) $post[$key] = array();
if (is_array($value)) merge_file_post_data($type, $value, $post[$key]);
else $post[$key][$type] = $value;
}
}
function get_file_post_data() {
$files = array(
'name' => array(),
'type' => array(),
'tmp_name' => array(),
'error' => array(),
'size' => array()
);
$post = $_POST;
// Flip the first level with the second:
foreach ($_FILES as $key_a => $data_a) {
foreach ($data_a as $key_b => $data_b) {
$files[$key_b][$key_a] = $data_b;
}
}
// Merge and make the first level the deepest level:
foreach ($files as $type => $data) {
merge_file_post_data($type, $data, $post);
}
return $post;
}
var_dump(get_file_post_data());
}
else echo '
<form action="" method="post" enctype="multipart/form-data">
<input name="MAX_FILE_SIZE" type="hidden" value="5242880">
<div><label class="file">Image A <input name="image-a" type="file"></label></div>
<div><label class="file">Image B <input name="image-b" type="file"></label></div>
<div><label class="file">Image C <input name="image[sub][c]" type="file"></label></div>
<div><button type="submit">Send</button></div>
</form>
';
?>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With