The attached "new FILES_flattened" class flattens the $_FILES array, for any combination of "single" files, multi-file arrays with given indices [i] or multi-file array with [] indices, even multi-level multi-file arrays [i][j]...[n].
An additional element "pos" in the flattened array will hold the "node path" for each file of a multi-file array, e.g. 'pos' => [ i, j ], so that it can be used for proper disposition of the file in database array, or for creating automated names that append each index level.
Most importantly, the HTML input "name" property and all other information remains fully intact.
HTML <form> snippet:
<input type="hidden" name="MAX_FILE_SIZE" value="2500000" title="Permitted bytes per file." />
<input type="file" name="pictures[4]" accept="image/*"/>
<input type="file" name="thumb" accept="image/*" />
<input type="file" name="pictures[]" accept="image/*" />
<input type="file" name="pictures[10][5]" accept="image/*" />
<input type="file" name="pictures[17]" accept="image/*" />
Result :
A flat array, one element per <input> field, each will have this structure:
...
'pictures' => array (size=6)
'name' => 'ClientFilename.jpg'
'type' => 'image/jpeg' (
'tmp_name' => '...\php8D2C.tmp'
'error' => 0
'size' => 1274994
'pos' => array (size=2)
0 => 10
1 => 5
...
with nothing more than a simple foreach:
<?php
foreach( new RecursiveIteratorIterator( new FILES_flattened ) as $key => $data ) {
var_dump( $key, $data );
// Here's how to use the "pos" element, to generate an automated name
// that incorporates the "node path", e.g. "picture[10][5]"
echo $key.( empty( $data[ 'pos' ] ) ? '' : '['. implode( '][', $data[ 'pos' ] ) . ']' );
}