Обработка многомерного массива $ _FILES - PullRequest
4 голосов
/ 19 сентября 2011

У меня есть следующий массив $_FILES для обработки из формы поддержки

Array
(
    [file] => Array
        (
            [name] => Array
                (
                    [0] => Test.jpg
                    [1] => Test.doc
                    [2] => Test.php
                    [3] => 
                )

            [type] => Array
                (
                    [0] => image/jpeg
                    [1] => image/jpeg
                    [2] => image/jpeg
                    [3] => 
                )

            [tmp_name] => Array
                (
                    [0] => /tmp/phpCO0vSD
                    [1] => /tmp/phpEFpp3Q
                    [2] => /tmp/phpwN4Iwc
                    [3] => 
                )

            [error] => Array
                (
                    [0] => 0
                    [1] => 0
                    [2] => 0
                    [3] => 4
                )

            [size] => Array
                (
                    [0] => 1305787
                    [1] => 339773
                    [2] => 480098
                    [3] => 0
                )

        )

)

Моя основная проблема заключается в понимании логики, необходимой для обработки массива, проверки правильности каждого файла (который у меня уже есть список допустимых расширений), а затем переименования и сохранения файла соответствующим образом.

Решения в Google и SO довольно сложны для моих простых требований.

Ответы [ 4 ]

6 голосов
/ 19 сентября 2011

Вот как вы бы проходили свой массив:

foreach ($_FILES['file']['name'] as $key => $name) {
    echo $name;
    echo $_FILES['file']['type'][$key];
    echo $_FILES['file']['tmp_name'][$key];
}

Имея этот цикл, вы можете легко делать то, что хотите.

5 голосов
/ 29 августа 2012

Я люблю foreach() так сильно, я всегда хожу с этим ...

$files = array();
foreach ($_FILES['files']['name'] as $num_key => $dummy) {
    foreach ($_FILES['files'] as $txt_key => $dummy) {
        $files[$num_key][$txt_key] = $_FILES['files'][$txt_key][$num_key];
    }
}

... а затем я снова использую foreach($files as $file) для удобной работы с данными. :)

Конечно, этот ответ от zerkms быстрее, но это общий подход к переупорядочению логики массива в любом случае - вы должны пройти его дважды (x * y).

3 голосов
/ 20 мая 2015

Вот более общее решение для ответа seoguru .Он работает с полями ввода файлов, имя которых содержит любой уровень вложенных массивов, например file, file[] (случай для этого вопроса), file[english], file[english][] и т. Д.

function rearrangeUploadArray(array $array) {
   if(!is_array(reset($array)))
      return $array;

   $rearranged = [];
   foreach($array as $property => $values)
      foreach($values as $key => $value)
         $rearranged[$key][$property] = $value;

   foreach($rearranged as &$value)
      $value = rearrangeUploadArray($value);

   return $rearranged;
}

Я понимаю, что этот ответ является более сложным, чем он должен быть для этого вопроса, но, возможно, он может быть полезным для кого-то когда-нибудь.Примером использования является локализованная форма загрузки, где несколько файлов могут быть загружены для разных языков.Тогда имеет смысл иметь одно поле для ввода файла для каждого языка, например, с именами file[english][], file[german][], file[spanish][] и т. Д. rearrangeUploadArray($_FILES['file']) будет возвращать массив в форме

Array
(
    [english] => Array
        (
            [0] => Array
                (
                    [name] => ...
                    [type] => ...
                    [tmp_name] => ...
                    [error] => ...
                    [size] => ...
                )

            [1] => Array
                (
                    [name] => ...
                    [type] => ...
                    [tmp_name] => ...
                    [error] => ...
                    [size] => ...
                )

            [...]
        )
    [german] => Array
        (
            [0] => Array
                (
                    [name] => ...
                    [type] => ...
                    [tmp_name] => ...
                    [error] => ...
                    [size] => ...
                )

            [...]
        )
    [spanish] => Array
        (
            [0] => Array
                (
                    [name] => ...
                    [type] => ...
                    [tmp_name] => ...
                    [error] => ...
                    [size] => ...
                )

            [...]
        )
)
2 голосов
/ 21 октября 2015

Другой вариант рекурсивного переупорядочения на основе решения clamcrusher из здесь

function getFixedFilesArray() {
    $walker = function ($arr, $fileInfokey, callable $walker) {
        $ret = array();
        foreach ($arr as $k => $v) {
            if (is_array($v)) {
                $ret[$k] = $walker($v, $fileInfokey, $walker);
            } else {
                $ret[$k][$fileInfokey] = $v;
            }
        }
        return $ret;
    };

    $files = array();
    foreach ($_FILES as $name => $values) {
        // init for array_merge
        if (!isset($files[$name])) {
            $files[$name] = array();
        }
        if (!is_array($values['error'])) {
            // normal syntax
            $files[$name] = $values;
        } else {
            // html array feature
            foreach ($values as $fileInfoKey => $subArray) {
                $files[$name] = array_replace_recursive($files[$name], $walker($subArray, $fileInfoKey, $walker));
            }
        }
    }

    return $files;
}

Основное отличие от исходного решения состоит в том, что я заменил array_merge_recursive на array_replace_recursive, чтобы индексированные массивы в деревене будет давать недопустимый результат (array_merge_recursive для индексированных массивов добавляет новые индексы вместо слияния с существующими индексами).Я проверил это в нескольких довольно сложных ситуациях, и это сработало, как и ожидалось

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...