简体   繁体   English

如何迭代PHP $ _FILES数组?

[英]How can I iterate PHP $_FILES array?

This might be stupid question, but PHPs array $_FILES has very odd format, which I have never used before. 这可能是一个愚蠢的问题,但PHPs数组$ _FILES有非常奇怪的格式,我以前从未使用过。 Can somebody tell me how can I iterate this array in sane way ? 有人能告诉我怎样才能以理智的方式迭代这个数组? I have used to iterate objects or object like arrays, but this format is very odd for me. 我曾经习惯迭代对象或类似数组的对象,但这种格式对我来说非常奇怪。 Is there any way to iterate this array like object array? 有没有办法像对象数组一样迭代这个数组?

( [attachments] => 
    Array ( 
        [name] => Array ( 
            [0] => test1.png 
            [1] => test2.png 
        ) 
        [type] => Array ( 
            [0] => image/png 
            [1] => image/png 
        ) 
        [tmp_name] => Array ( 
            [0] => /tmp/phpmFkEUe 
            [1] => /tmp/phpbLtZRw 
        )
        [error] => Array ( 
            [0] => 0 
            [1] => 0 
        ) 
        [size] => Array ( 
            [0] => 9855 
            [1] => 3002 
        ) 
    ) 
)

Wow, that indeed is odd, are you using <input type="file" name="attachments[]" /> in your markup? 哇,确实很奇怪,你在标记中使用<input type="file" name="attachments[]" />吗? If you could afford to change those using unique name= , you won't have that odd format... 如果您能够使用唯一name=更改那些,您将不会有那种奇怪的格式......

To directly answer your question, try: 要直接回答您的问题,请尝试:

$len = count($_FILES['attachments']['name']);

for($i = 0; $i < $len; $i++) {
   $fileSize = $_FILES['attachments']['size'][$i];
   // change size to whatever key you need - error, tmp_name etc
}

I always thought that this structure was nonsense. 我一直认为这种结构是无稽之谈。 So whenever I use a multiple input file field, I do this: 所以每当我使用多输入文件字段时,我这样做:

$files = array_map('RemapFilesArray'
    (array) $_FILES['attachments']['name'],
    (array) $_FILES['attachments']['type'],
    (array) $_FILES['attachments']['tmp_name'],
    (array) $_FILES['attachments']['error'],
    (array) $_FILES['attachments']['size']
);

function RemapFilesArray($name, $type, $tmp_name, $error, $size)
{
    return array(
        'name' => $name,
        'type' => $type,
        'tmp_name' => $tmp_name,
        'error' => $error,
        'size' => $size,
    );
}

Then you will have an array that you can iterate and each item in it will be an associative array of the same structure that you would get with a normal, single file input. 然后你将拥有一个可以迭代的数组,其中的每个项目都是一个与普通单个文件输入相同结构的关联数组。 So, if you already have some function for handling those, you can just pass each of these items to it and it will not require any modification. 因此,如果您已经有一些处理它们的功能,您只需将这些项目传递给它,它就不需要任何修改。

By the way, the reason to cast all inputs as array is so that this will work even if you forgot to put the [] on the name of your file input (of course you will only get one file in that case, but it's better than breaking). 顺便说一句,将所有输入转换为数组的原因是,即使您忘记将[]放在文件输入的名称上,这也会起作用(当然,在这种情况下你只能得到一个文件,但它更好比打破)。

The simplest way is: 最简单的方法是:

$files = $_FILES['attachments']['name'];
$count = 0;
foreach ($files as $file) {
     $file_name = $file;
     $file_type = $_FILES['attachments']['type'][$count];
     $file_size = $_FILES['attachments']['size'][$count];
     ...
     ...

     ++$count;
}

This is the only way to iterate $_FILES. 这是迭代$ _FILES的唯一方法。

foreach ($_FILES['attachments']['tmp_name'] as $k => $v) {
  echo $_FILES['attachments']['name'][$k];
  echo $_FILES['attachments']['type'][$k];
}

this way? 这条路?

foreach((array)$_FILES["attachments"] as $val) {
   foreach((array)$val["name"] as $name) {
      // $name = "test1.png",...
   }
   foreach((array)$val["type"] as $type) {
      // $type = "imagepng",...
   }   
}

I had the same problem while doing multipart forms. 我在做多部分表单时遇到了同样的问题。 Basically I needed to check if theres any file uploads first with 'isset' and then go through every file and do all necessary conditionals. 基本上我需要检查是否有任何文件首先使用'isset'上传,然后浏览每个文件并执行所有必要的条件。

The fastest way is just to pick one array index element, like ['tmp_name'] and loop that with foreach: 最快的方法是选择一个数组索引元素,如['tmp_name']并使用foreach循环:

if(isset($_FILES['attachments']) {
   foreach($_FILES['attachments']['tmp_name'] as $key => $value) {
      //do stuff you need/like
   }
}

The main reason to use arrays for multiple file uploads, is that in the end it's much easier to process and iterate. 使用数组进行多个文件上传的主要原因是,最终它更容易处理和迭代。 If you use unique names like attachment 1, attachment 2 you run into many problems in more complex situations. 如果使用附件1,附件2等唯一名称,则在更复杂的情况下会遇到许多问题。 I for example, had other upload fields for different attachment categories. 例如,我有其他上传字段用于不同的附件类别。

Of course you can do a method, as mentioned before, that fixes the $_FILES array into more clever form, if you find the whole array problematic. 当然,如果您发现整个数组有问题,您可以执行一个方法,如前所述,将$_FILES数组修复为更聪明的形式。

I have tried small demonstration , have a look 我试过小型演示,看看

<html>
<body>
<form enctype="multipart/form-data" method="post">
<input type="file" name="file[]" />
<input type="file" name="file[]" />

<input type="submit" name="submit" />
</form>
<body>
</html>
<?php
if($_SERVER['REQUEST_METHOD']=='POST'){
    foreach ($_FILES as $k=>$v){
   if(is_array($v)){
       foreach ($v as $sk=>$sv){ 
                $arr[$sk][$k]=$sv;
        }
       }
    }
  echo "<pre>";
  print_r($arr);
 }
?>

Output 产量

Array
(
    [name] => Array
        (
            [file] => Array
                (
                    [0] => 4_Milestone text (1).doc
                    [1] => 2x5 ko condolence ad.jpg
                )

        )

    [type] => Array
        (
            [file] => Array
                (
                    [0] => application/msword
                    [1] => image/jpeg
                )

        )

    [tmp_name] => Array
        (
            [file] => Array
                (
                    [0] => C:\xampp\tmp\php15EF.tmp
                    [1] => C:\xampp\tmp\php163E.tmp
                )

        )

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

        )

    [size] => Array
        (
            [file] => Array
                (
                    [0] => 20480
                    [1] => 56642
                )

        )

)

Here you go: Below function will help you simplify the file upload in a way that you will be able to process it similar to single upload of the file instead of multiple file upload. 在这里:下面的功能将帮助您以一种您可以处理它的方式简化文件上传,类似于单个上载文件而不是多个文件上载。

HTML: (form.html) HTML:(form.html)

<form method="post" action="post.php" enctype="multipart/form-data">
<input type="file" name="attachment[]" />
<input type="file" name="attachment[]" />
<input type="file" name="attachment[]" />
<input type="submit" value="Upload" />

PHP: (post.php) PHP:(post.php)

<?php
function simplifyMultiFileArray($files = array())
{
    $sFiles = array();
    if(is_array($files) && count($files) > 0)
    {
        foreach($files as $key => $file)
        {
            foreach($file as $index => $attr)
            {
                $sFiles[$index][$key] = $attr;
            }
        }
    }
    return $sFiles;
}

$sFiles = simplifyMultiFileArray($_FILES['attachment']);
echo '<pre>';
print_r($sFiles);
?>

There are many ways to clean up the $_FILES array and make it more sensible. 有许多方法可以清理$ _FILES数组并使其更加合理。 Here's my prefered way: 这是我的首选方式:

foreach ($_FILES as $fieldname => $keys)
{
    foreach ($keys as $key => $list)
    {
        foreach ($list as $no => $value)
        {
            $files[$fieldname][$no][$key] = $value;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM