Как вы перебираете массив $ _FILES?

Вот входы, которые я хочу прокрутить

Main photo: <input type="file" name="image[]" /> Side photo 1: <input type="file" name="image[]" /> Side photo 2: <input type="file" name="image[]" /> Side photo 3: <input type="file" name="image[]" /> 

Произошла пара странных вещей, когда я ничего не загружал, я использую count($_FILES['image']) , я повторил эту функцию и вернул значение 5. В этом массиве не должно быть элементов. Почему есть один дополнительный вход, когда у меня есть только 4 файла?

Теперь, используя собственно цикл, я пытаюсь использовать цикл foreach, но он не работает.

 foreach($_FILES['image'] as $files){echo $files['name']; } 

Ничего не получилось, что я в конечном итоге хотел бы сделать, это просмотреть все изображения, убедиться, что они соответствуют формату, размеру и переименованию каждого из них. Но этот простой цикл foreach () показывает, что каким-то образом я не могу даже пропустить массив $ _FILES, а count () еще больше смутил меня, когда он сказал, что в массиве есть 5 элементов, когда я даже ничего не загружал.

Solutions Collecting From Web of "Как вы перебираете массив $ _FILES?"

Ваша примерная форма должна работать нормально. Просто вы ожидаете, что структура $_FILES будет отличаться, чем на самом деле, когда используется структура массива для имен полей.

Структура этого многомерного массива выполняется следующим образом:

 $_FILES[fieldname] => array( [name] => array( /* these arrays are the size you expect */ ) [type] => array( /* these arrays are the size you expect */ ) [tmp_name] => array( /* these arrays are the size you expect */ ) [error] => array( /* these arrays are the size you expect */ ) [size] => array( /* these arrays are the size you expect */ ) ); 

Поэтому count( $_FILES[ "fieldname" ] ) даст 5 .
Но подсчет более глубоких измерений также не приведет к ожидаемому результату. Например, подсчет полей со count( $_FILES[ "fieldname" ][ "tmp_name" ] ) всегда будет приводить к количеству полей файла, а не количеству фактически загруженных файлов. Вам все равно придется перебирать элементы, чтобы определить, было ли что-либо загружено для определенного поля файла.

РЕДАКТИРОВАТЬ
Таким образом, чтобы прокрутить поля, вы сделали бы что-то вроде следующего:

 // !empty( $_FILES ) is an extra safety precaution // in case the form's enctype="multipart/form-data" attribute is missing // or in case your form doesn't have any file field elements if( strtolower( $_SERVER[ 'REQUEST_METHOD' ] ) == 'post' && !empty( $_FILES ) ) { foreach( $_FILES[ 'image' ][ 'tmp_name' ] as $index => $tmpName ) { if( !empty( $_FILES[ 'image' ][ 'error' ][ $index ] ) ) { // some error occured with the file in index $index // yield an error here return false; // return false also immediately perhaps?? } /* edit: the following is not necessary actually as it is now defined in the foreach statement ($index => $tmpName) // extract the temporary location $tmpName = $_FILES[ 'image' ][ 'tmp_name' ][ $index ]; */ // check whether it's not empty, and whether it indeed is an uploaded file if( !empty( $tmpName ) && is_uploaded_file( $tmpName ) ) { // the path to the actual uploaded file is in $_FILES[ 'image' ][ 'tmp_name' ][ $index ] // do something with it: move_uploaded_file( $tmpName, $someDestinationPath ); // move to new location perhaps? } } } 

Для получения дополнительной информации см. Документы .

просто переименуйте свои поля таким образом

 Main photo: <input type="file" name="image1" /> Side photo 1: <input type="file" name="image2" /> Side photo 2: <input type="file" name="image3" /> Side photo 3: <input type="file" name="image4" /> 

и тогда вы сможете обычным образом выполнить итерацию:

 foreach($_FILES as $file){ echo $file['name']; } 

Короткая функция для перестроения $ _FILES ['files'] в более ожидаемую структуру.

 function restructureFilesArray($files) { $output = []; foreach ($files as $attrName => $valuesArray) { foreach ($valuesArray as $key => $value) { $output[$key][$attrName] = $value; } } return $output; } 

Я придумал решение, которое работает для массивов $ _FILES произвольной глубины. В качестве быстрого объяснения вам нужен алгоритм, который делает это:

 For each subtree in the file tree that's more than one item deep: For each leaf of the subtree: $leaf[a][b][c] ... [y][z] -> $result[z][a][b][c] ... [y] 

Вот какой код действительно работает.

 function sane_file_array($files) { $result = array(); $name = array(); $type = array(); $tmp_name = array(); $error = array(); $size = array(); foreach($files as $field => $data) { foreach($data as $key => $val) { $result[$field] = array(); if(!is_array($val)) { $result[$field] = $data; } else { $res = array(); files_flip($res, array(), $data); $result[$field] += $res; } } } return $result; } function array_merge_recursive2($paArray1, $paArray2) { if (!is_array($paArray1) or !is_array($paArray2)) { return $paArray2; } foreach ($paArray2 AS $sKey2 => $sValue2) { $paArray1[$sKey2] = array_merge_recursive2(@$paArray1[$sKey2], $sValue2); } return $paArray1; } function files_flip(&$result, $keys, $value) { if(is_array($value)) { foreach($value as $k => $v) { $newkeys = $keys; array_push($newkeys, $k); files_flip($result, $newkeys, $v); } } else { $res = $value; // Move the innermost key to the outer spot $first = array_shift($keys); array_push($keys, $first); foreach(array_reverse($keys) as $k) { // You might think we'd say $res[$k] = $res, but $res starts out not as an array $res = array($k => $res); } $result = array_merge_recursive2($result, $res); } } 

Просто вызовите sane_files_array на $ _FILES, и вам должно быть хорошо идти, независимо от глубины массива $ _FILES. Это действительно должно быть частью самого языка, потому что форматирование массива $ _FILES абсолютно нелепо.

Может быть:

 Main photo: <input type="file" name="image1" /> Side photo 1: <input type="file" name="image2" /> Side photo 2: <input type="file" name="image3" /> Side photo 3: <input type="file" name="image4" /> 

 $i=1; while (isset($_FILES['image'.$i])) { print_r($_FILES['image'.$i]); $i++; } 

Если вам нужно перебирать определенные поля файла.

Выбор PHP, как обрабатывать $ _FILES, тратит много времени на разработку. Основываясь на ответе @ Lendrick, здесь есть аналогичный подход OO.

 /** * @brief get the POSTed files in a more usable format Works on the following methods: <form method="post" action="/" name="" enctype="multipart/form-data"> <input type="file" name="photo1" /> <input type="file" name="photo2[]" /> <input type="file" name="photo2[]" /> <input type="file" name="photo3[]" multiple /> * @return Array * @todo * @see http://stackoverflow.com/questions/5444827/how-do-you-loop-through-files-array */ public static function GetPostedFiles() { /* group the information together like this example Array ( [attachments] => Array ( [0] => Array ( [name] => car.jpg [type] => image/jpeg [tmp_name] => /tmp/phpe1fdEB [error] => 0 [size] => 2345276 ) ) [jimmy] => Array ( [0] => Array ( [name] => 1.jpg [type] => image/jpeg [tmp_name] => /tmp/phpx1HXrr [error] => 0 [size] => 221041 ) [1] => Array ( [name] => 2 ' .jpg [type] => image/jpeg [tmp_name] => /tmp/phpQ1clPh [error] => 0 [size] => 47634 ) ) ) */ $Result = array(); $Name = array(); $Type = array(); $TmpName = array(); $Error = array(); $Size = array(); foreach($_FILES as $Field => $Data) { foreach($Data as $Key => $Val) { $Result[$Field] = array(); if(!is_array($Val)) $Result[$Field] = $Data; else { $Res = array(); self::GPF_FilesFlip($Res, array(), $Data); $Result[$Field] += $Res; } } } return $Result; } private static function GPF_ArrayMergeRecursive($PaArray1, $PaArray2) { // helper method for GetPostedFiles if (!is_array($PaArray1) or !is_array($PaArray2)) return $PaArray2; foreach ($PaArray2 AS $SKey2 => $SValue2) $PaArray1[$SKey2] = self::GPF_ArrayMergeRecursive(@$PaArray1[$SKey2], $SValue2); return $PaArray1; } private static function GPF_FilesFlip(&$Result, $Keys, $Value) { // helper method for GetPostedFiles if(is_array($Value)) { foreach($Value as $K => $V) { $NewKeys = $Keys; array_push($NewKeys, $K); self::GPF_FilesFlip($Result, $NewKeys, $V); } } else { $Res = $Value; // move the innermost key to the outer spot $First = array_shift($Keys); array_push($Keys, $First); foreach(array_reverse($Keys) as $K) $Res = array($K => $Res); // you might think we'd say $Res[$K] = $Res, but $Res starts out not as an array $Result = self::GPF_ArrayMergeRecursive($Result, $Res); } } 

Я боролся с этой дилеммой почти неделю! Ничто из того, что я нашел в сети, не могло мне помочь. Я знал, что делать, но не мог понять, как правильно перебирать массив $ _FILES – до сих пор, когда я читал отредактированный пост принятого ответа.

Я сделал некоторые изменения, хотя, в сценарии, как опубликовано, так как это не работает должным образом для меня. Я хотел бы определить, был ли вообще выбран файл, поэтому я изменил строку «if (! Empty ($ _FILES ['image'] ['error'] [$ index]))" to "if (! empty ($ _FILES ['image'] ['size'] [$ index])), а затем вместо «return false;» вместо этого я вставляю размер в переменную: «$ Size = $ _FILES ['upload' ] ['size'] [$ index]; "

Таким образом, я мог проверить, была ли переменная $ Size больше нуля. Если это так, то был выбран файл, и я мог бы продолжить подсчет количества файлов и фактическую загрузку. Я не использовал какой-либо «лишний» скрипт после «return false», в принятом ответе. Надеюсь, это поможет кому-то.

: P / MacD