3 * @see https://github.com/zendframework/zend-diactoros for the canonical source repository
4 * @copyright Copyright (c) 2018 Zend Technologies USA Inc. (https://www.zend.com)
5 * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License
8 namespace Zend\Diactoros;
10 use InvalidArgumentException;
11 use Psr\Http\Message\UploadedFileInterface;
13 use function is_array;
16 * Normalize uploaded files
18 * Transforms each value into an UploadedFile instance, and ensures that nested
19 * arrays are normalized.
22 * @return UploadedFileInterface[]
23 * @throws InvalidArgumentException for unrecognized values
25 function normalizeUploadedFiles(array $files)
28 * Traverse a nested tree of uploaded file specifications.
30 * @param string[]|array[] $tmpNameTree
31 * @param int[]|array[] $sizeTree
32 * @param int[]|array[] $errorTree
33 * @param string[]|array[]|null $nameTree
34 * @param string[]|array[]|null $typeTree
35 * @return UploadedFile[]|array[]
37 $recursiveNormalize = function (
41 array $nameTree = null,
42 array $typeTree = null
43 ) use (&$recursiveNormalize) {
45 foreach ($tmpNameTree as $key => $value) {
46 if (is_array($value)) {
48 $normalized[$key] = $recursiveNormalize(
52 isset($nameTree[$key]) ? $nameTree[$key] : null,
53 isset($typeTree[$key]) ? $typeTree[$key] : null
57 $normalized[$key] = createUploadedFile([
58 'tmp_name' => $tmpNameTree[$key],
59 'size' => $sizeTree[$key],
60 'error' => $errorTree[$key],
61 'name' => isset($nameTree[$key]) ? $nameTree[$key] : null,
62 'type' => isset($typeTree[$key]) ? $typeTree[$key] : null
69 * Normalize an array of file specifications.
71 * Loops through all nested files (as determined by receiving an array to the
72 * `tmp_name` key of a `$_FILES` specification) and returns a normalized array
73 * of UploadedFile instances.
75 * This function normalizes a `$_FILES` array representing a nested set of
76 * uploaded files as produced by the php-fpm SAPI, CGI SAPI, or mod_php
80 * @return UploadedFile[]
82 $normalizeUploadedFileSpecification = function (array $files = []) use (&$recursiveNormalize) {
83 if (! isset($files['tmp_name']) || ! is_array($files['tmp_name'])
84 || ! isset($files['size']) || ! is_array($files['size'])
85 || ! isset($files['error']) || ! is_array($files['error'])
87 throw new InvalidArgumentException(sprintf(
88 '$files provided to %s MUST contain each of the keys "tmp_name",'
89 . ' "size", and "error", with each represented as an array;'
90 . ' one or more were missing or non-array values',
95 return $recursiveNormalize(
99 isset($files['name']) ? $files['name'] : null,
100 isset($files['type']) ? $files['type'] : null
105 foreach ($files as $key => $value) {
106 if ($value instanceof UploadedFileInterface) {
107 $normalized[$key] = $value;
111 if (is_array($value) && isset($value['tmp_name']) && is_array($value['tmp_name'])) {
112 $normalized[$key] = $normalizeUploadedFileSpecification($value);
116 if (is_array($value) && isset($value['tmp_name'])) {
117 $normalized[$key] = createUploadedFile($value);
121 if (is_array($value)) {
122 $normalized[$key] = normalizeUploadedFiles($value);
126 throw new InvalidArgumentException('Invalid value in files specification');