【问题标题】:PHP: parse $_FILES[] data in multidimesional arrayPHP:解析多维数组中的 $_FILES[] 数据
【发布时间】:2011-05-29 19:35:37
【问题描述】:

我有一个允许动态复制表单域的表单。该表单允许文件上传和文本输入,因此数据在 $_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'];
    }

}

但我收到“未定义的索引:文件...”错误。如何解析发布的值。

【问题讨论】:

  • 可能的。使用 print_r($_FILES) 和 print_r($_POST) 设计一种方法使其匹配。 $_FILES 有一个覆盖数组结构。所以,重命名。
  • 谢谢马里奥,我正在调查这个。
  • 如果您包含一些来自 print_r($_FILES) 和 print_r($_POST) 的示例输出,我们可能会为您提供帮助。
  • @GWW 我在这里保存了一个临时脚本:superuntitled.com/temp.php

标签: php file-upload


【解决方案1】:

更新

表格:

<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 上传)

大批 ( [1] => 数组 ( [问题] => AAA [答案] => 数组 ( [文本] => 数组 ( [0] => bbb [1] => 抄送 ) ) [question_file] => 数组 ( [名称] => test.txt [类型] => 文本/纯文本 [tmp_name] => /tmp/phpqef5eL [错误] => 0 [大小] => 0 ) [answer_file] => 数组 ( [文件] => 数组 ( [名称] => 数组 ( [0] => test.txt [1] => 测试.txt ) [类型] => 数组 ( [0] => 文本/纯文本 [1] => 文本/纯文本 ) [tmp_name] => 数组 ( [0] => /tmp/phpc2sdMs [1] => /tmp/phpzKNnja ) [错误] => 数组 ( [0] => 0 [1] => 0 ) [大小] => 数组 ( [0] => 0 [1] => 0 ) ) ) ) )

【讨论】:

  • 感谢 ajreal,我没有在我的问题中包含这个,但它们肯定在我的代码中!
  • @superUntitled - 前面提到过,&lt;form action="temp2.php" method="post"&gt; 不完整,试试&lt;form action="temp2.php" method="post" enctype="multipart/form-data"&gt;
  • +1 抓住了这一点!我已经更新了文件,但是 $rtn 数组是空的。
【解决方案2】:

当您上传文件名以多维数组格式指定的文件时,PHP 似乎不喜欢它。鉴于 POST 和 FILEs 数据在 PHP 中完全分开,您应该重新调整您的表单。 “question[1]”格式是可以的,但不是“question[1][file]”。相反,尝试类似:

<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'];
}

【讨论】:

  • 谢谢 Marc,我正在尝试。
【解决方案3】:

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

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

您可以在页面 cmets 中找到各种各样的代码 sn-ps,所有这些代码都处理这种烦恼。实际上,大多数 cmets 都是这样的!

【讨论】:

    【解决方案4】:

    当您一次处理多个文件时,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'];
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-12
      • 1970-01-01
      • 2019-06-13
      • 1970-01-01
      • 1970-01-01
      • 2020-11-23
      相关资源
      最近更新 更多