Skip to content

Instantly share code, notes, and snippets.

@umidjons
Created March 31, 2014 14:35
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save umidjons/9893735 to your computer and use it in GitHub Desktop.
Save umidjons/9893735 to your computer and use it in GitHub Desktop.
Normalize $_FILES array when uploading multiple files (from php.net)

Normalize $_FILES array when uploading multiple files

When uploading multiple files, the $_FILES variable is created in the form:

Array
(
    [name] => Array
        (
            [0] => foo.txt
            [1] => bar.txt
        )

    [type] => Array
        (
            [0] => text/plain
            [1] => text/plain
        )

    [tmp_name] => Array
        (
            [0] => /tmp/phpYzdqkD
            [1] => /tmp/phpeEwEWG
        )

    [error] => Array
        (
            [0] => 0
            [1] => 0
        )

    [size] => Array
        (
            [0] => 123
            [1] => 456
        )
)

It would be cleaner if the uploaded files array in the form:

Array
(
    [0] => Array
        (
            [name] => foo.txt
            [type] => text/plain
            [tmp_name] => /tmp/phpYzdqkD
            [error] => 0
            [size] => 123
        )

    [1] => Array
        (
            [name] => bar.txt
            [type] => text/plain
            [tmp_name] => /tmp/phpeEwEWG
            [error] => 0
            [size] => 456
        )
)

We can convert $_FILES array to cleaner one with this function:

<?php
function normalizeFiles( &$files )
{
	$_files       = [ ];
	$_files_count = count( $files[ 'name' ] );
	$_files_keys  = array_keys( $files );

	for ( $i = 0; $i < $_files_count; $i++ )
		foreach ( $_files_keys as $key )
			$_files[ $i ][ $key ] = $files[ $key ][ $i ];

	return $_files;
}

Then we can use it like so:

<?php
if ( $_FILES[ 'upload' ] )
{
	$files = normalizeFiles( $_FILES[ 'myfiles' ] );
	foreach ( $files as $file )
	{
		print 'File Name: ' . $file[ 'name' ] . "<br>\n";
		print 'File Type: ' . $file[ 'type' ] . "<br>\n";
		print 'File Size: ' . $file[ 'size' ] . "<br><br>\n";
	}
}

Output:

File Name: shanideveloper-blogspot-com.pdf
File Type: application/pdf
File Size: 175928

File Name: Packtpub.Yii.1.1.Application.Development.Cookbook.Aug.2011.rar
File Type: application/octet-stream
File Size: 5960406
@Mrten
Copy link

Mrten commented May 27, 2020

keep in mind that it is always possible to have more depth in the array, for example:

<input type='file' name='field[file][]>
<input type='file' name='field[file][]>

@burzum
Copy link

burzum commented Jun 22, 2020

@Mrten of course, but do you have a good solution to this? :)

@Mrten
Copy link

Mrten commented Oct 19, 2020

sure:

function normalizeFiles() {
	$out = [];
	foreach ($_FILES as $key => $file) {
		if (isset($file['name']) && is_array($file['name'])) {
			$new = [];
			foreach (['name', 'type', 'tmp_name', 'error', 'size'] as $k) {
				array_walk_recursive($file[$k], function (&$data, $key, $k) {
					$data = [$k => $data];
				}, $k);
				$new = array_replace_recursive($new, $file[$k]);
			}
			$out[$key] = $new;
		} else {
			$out[$key] = $file;
		}
	}
	return $out;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment