PHP:在多维数组中解析$ _FILES []数据

时间:2010-12-23 06:15:46

标签: php file-upload

我有一个允许动态复制表单字段的表单。该表单允许文件上传和文本输入,因此数据在$ _POST和$ _FILES数组中发送。

初始输入集如下所示:

<input type="text" name="question[1][text]"  />
<input  type="file" name="question[1][file]"  /> 

<input type="text" class="a" name="answer[1][text][]"  /> 
<input  type="file" name="answer[1][file][]"  /> 

当重复字段递增时,它们看起来像这样:

<input type="text" name="question[2][text]"  />
<input  type="file" name="question[2][file]"  /> 

<input type="text" class="a" name="answer[2][text][]"  /> 
<input  type="file" name="answer[2][file][]"  /> 

为了使问题复杂化,“答案”表单字段也可以复制(因此“答案”名称数组末尾的[]。

如何解析发布的$ _FILES数组?我尝试过这样的事情:

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

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

}

但是我收到了“Undefined index:file ...”错误。如何解析发布的值。

4 个答案:

答案 0 :(得分:3)

<强>更新

形式:

<form method="post" enctype="multipart/form-data">
<input type="text" name="question[1][text]"  value="AAA"/>
<input type="file" name="question[1][file]"  />
<input type="text" name="answer[1][text][0]" value="bbb" />
<input type="file" name="answer[1][file][0]"  />
<input type="text" name="answer[1][text][1]" value="ccc" />
<input type="file" name="answer[1][file][1]"  />
<input type="submit"/>

PHP:

$rtn = array();
foreach ($_POST['question'] as $key=>$arr)
{
  if (!isset($rtn[$key])) 
  {
    $rtn[$key] = array('question'=>'', 'answer'=>array());
  }
  $rtn[$key]['question'] = $arr['text'];


  $tmp = array();
  foreach ($_FILES['question'] as $fkey=>$farr)
  {
    $tmp[$fkey] = $farr[$key]['file'];
  }
  $rtn[$key]['question_file']  = $tmp;

  $rtn[$key]['answer']['text'] = $_POST['answer'][$key]['text'];
}

foreach ($_FILES['answer'] as $key=>$arr)
{
  foreach ($arr as $answer_idx=>$farr)
  {
    foreach ($farr as $file_index=>$file)
    {
      $rtn[$answer_idx]['answer_file'][$file_index][$key] = $file;
    }
  }
}

输出(使用test.txt上传)

Array
(
    [1] => Array
        (
            [question] => AAA
            [answer] => Array
                (
                    [text] => Array
                        (
                            [0] => bbb
                            [1] => ccc
                        )

                )

            [question_file] => Array
                (
                    [name] => test.txt
                    [type] => text/plain
                    [tmp_name] => /tmp/phpqef5eL
                    [error] => 0
                    [size] => 0
                )

            [answer_file] => Array
                (
                    [file] => Array
                        (
                            [name] => Array
                                (
                                    [0] => test.txt
                                    [1] => test.txt
                                )

                            [type] => Array
                                (
                                    [0] => text/plain
                                    [1] => text/plain
                                )

                            [tmp_name] => Array
                                (
                                    [0] => /tmp/phpc2sdMs
                                    [1] => /tmp/phpzKNnja
                                )

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

                            [size] => Array
                                (
                                    [0] => 0
                                    [1] => 0
                                )

                        )

                )

        )

)

答案 1 :(得分:2)

当您上传具有多维数组格式指定的文件名的文件时,PHP似乎不喜欢它。鉴于POST和FILEs数据在PHP中完全独立,您应该重新调整表单。 “问题[1]”格式没问题,但不是“问题[1] [文件]”。相反,尝试类似的东西:

<input type="text" name="question[1][text]"  />
<input  type="file" name="file[1]"  /> 

<input type="text" name="question[2][text]"  />
<input  type="file" name="file[2]"  /> 

只要您为文件字段和所有其他字段保留相同的索引值,就可以在表单处理期间访问文件,如下所示:

foreach(array_keys($_POST['question']) as $key {
     $file_is = $_FILES['file'][$key]['tmp_name'];
     $question_text = $_POST['question][$key]['text'];
}

答案 2 :(得分:0)

PHP以不合需要的方式“重新排序”$ _FILES数组。如果您访问PHP手册,请参阅讨论多个文件上传的页面:

http://www.php.net/manual/en/features.file-upload.multiple.php

您可以在页面评论中找到各种各样的代码片段,所有代码片段都处理此烦恼。实际上,大多数评论都与此有关!

答案 3 :(得分:0)

当您一次处理多个文件时,PHP $_FILES数组会变得疯狂。当您要处理多个输入而每个输入可能占用多个文件时,情况更糟。我写了一个使用$_FILES数组的库,并给了您一个副本,它按照您的想象重新排列。

实际上,最终使我为该问题写出可靠解决方案的情况与您的情况非常相似。请参阅自述文件中有关处理multiple fields that take multiple files的部分。

安装tvanc/files-array-organizer

composer require tvanc/files-array-organizer

组织$_FILES

只需对代码进行一些细微调整,就可以像尝试执行的那样遍历文件。

use tvanc\FilesArrayOrganizer\FilesArrayOrganizer;

// Use composer's autoload.php
require 'vendor/autoload.php';

$organizedFiles = FilesArrayOrganizer::organize($_FILES);

foreach ($organizedFiles['question'] as $q_index => $question)
{ 
    echo  $question['file']['name'];

    foreach ($organizedFiles['answer'][$q_index]['file'] as $answer_file)
    { 
        echo  $answer_file['name'];
    }

}