4 * @see https://github.com/laminas/laminas-diactoros for the canonical source repository
5 * @copyright https://github.com/laminas/laminas-diactoros/blob/master/COPYRIGHT.md
6 * @license https://github.com/laminas/laminas-diactoros/blob/master/LICENSE.md New BSD License
9 declare(strict_types=1);
11 namespace Laminas\Diactoros;
13 use Psr\Http\Message\UploadedFileInterface;
15 use function is_array;
18 * Normalize uploaded files
20 * Transforms each value into an UploadedFile instance, and ensures that nested
21 * arrays are normalized.
23 * @return UploadedFileInterface[]
24 * @throws Exception\InvalidArgumentException for unrecognized values
26 function normalizeUploadedFiles(array $files) : array
29 * Traverse a nested tree of uploaded file specifications.
31 * @param string[]|array[] $tmpNameTree
32 * @param int[]|array[] $sizeTree
33 * @param int[]|array[] $errorTree
34 * @param string[]|array[]|null $nameTree
35 * @param string[]|array[]|null $typeTree
36 * @return UploadedFile[]|array[]
38 $recursiveNormalize = function (
42 array $nameTree = null,
43 array $typeTree = null
44 ) use (&$recursiveNormalize) : array {
46 foreach ($tmpNameTree as $key => $value) {
47 if (is_array($value)) {
49 $normalized[$key] = $recursiveNormalize(
53 $nameTree[$key] ?? null,
54 $typeTree[$key] ?? null
58 $normalized[$key] = createUploadedFile([
59 'tmp_name' => $tmpNameTree[$key],
60 'size' => $sizeTree[$key],
61 'error' => $errorTree[$key],
62 'name' => $nameTree[$key] ?? null,
63 'type' => $typeTree[$key] ?? null,
70 * Normalize an array of file specifications.
72 * Loops through all nested files (as determined by receiving an array to the
73 * `tmp_name` key of a `$_FILES` specification) and returns a normalized array
74 * of UploadedFile instances.
76 * This function normalizes a `$_FILES` array representing a nested set of
77 * uploaded files as produced by the php-fpm SAPI, CGI SAPI, or mod_php
81 * @return UploadedFile[]
83 $normalizeUploadedFileSpecification = function (array $files = []) use (&$recursiveNormalize) : array {
84 if (! isset($files['tmp_name']) || ! is_array($files['tmp_name'])
85 || ! isset($files['size']) || ! is_array($files['size'])
86 || ! isset($files['error']) || ! is_array($files['error'])
88 throw new Exception\InvalidArgumentException(sprintf(
89 '$files provided to %s MUST contain each of the keys "tmp_name",'
90 . ' "size", and "error", with each represented as an array;'
91 . ' one or more were missing or non-array values',
96 return $recursiveNormalize(
100 $files['name'] ?? null,
101 $files['type'] ?? null
106 foreach ($files as $key => $value) {
107 if ($value instanceof UploadedFileInterface) {
108 $normalized[$key] = $value;
112 if (is_array($value) && isset($value['tmp_name']) && is_array($value['tmp_name'])) {
113 $normalized[$key] = $normalizeUploadedFileSpecification($value);
117 if (is_array($value) && isset($value['tmp_name'])) {
118 $normalized[$key] = createUploadedFile($value);
122 if (is_array($value)) {
123 $normalized[$key] = normalizeUploadedFiles($value);
127 throw new Exception\InvalidArgumentException('Invalid value in files specification');