PHP文件输入数组命名与其他输入不同

时间:2015-07-02 12:28:41

标签: php file-upload

我正在PHP中实现一个多用途html表单发布代码,能够发布对象图结构。

所以我创建了一些命名规则并基于它们,我在服务器端解析索引。

其中一条规则是这样的:

<input name="myModels[children[0]]" type="text" />

当然,上面的命名有点缩短,以便轻松达到目的。

当我从

中检索它时,该命名工作正常
  

$ _ POST

但是当我在文件输入中使用它时,它们永远不会出现在$ _FILE全局数组中 和

print_r($_FILES);

为空

根据file upload php manual

  

即使有文件,PHP也支持HTML数组功能。

那为什么呢?为什么这种类型的命名([]内部的[])适用于POSTED数据,但不适用于文件数据。

请注意,上传文件本身并不是问题 即使使用数组,上传工作仍然有效。即使是带有键索引的数组。

我想弄清楚的是:

<form action="/Test/uploadTest.php" method="post" enctype="multipart/form-data" >
    File1 <input name="myModels[postedFiles[0]]" type="file" /></br>
    File2 <input name="myModels[postedFiles[1]]" type="file" /></br>
    <input type="submit" value="post" />
</form> 

在uploadTest.php的服务器上

print_r($_FILES);

是空的。

我的PHP版本有点旧,它是PHP 5.3.6-13。您是否认为我的PHP版本或某些类型的错误即使在较新版本的PHP中也是如此?

提前致谢。

解决方案:@ tozer83和@alvaro提供的答案都非常有用。现在事实证明,多部分表单在处理非标量索引和试图获得带有文件输入的html数组的优势时有某种不同,以便创建用于创建复杂对象图的表达式,就像其他语言中的其他框架不会用PHP工作。应该忽略html数组或使用括号等其他文字来解决这个问题。 有点难以决定应该点击哪个复选标记!考虑到@alvoro已经获得的这个高级别,我决定选择@tozer83的答案,因为他先回答并给出了解决方案。但@ alvaro的答案也很详细,也很有帮助。所以我给他的答案+1。

2 个答案:

答案 0 :(得分:2)

首先(只是为了清楚地说明)PHP不允许非标量值作为数组键。实际上,只能使用字符串和整数。因此,没有语言结构可以容纳像casper.start(URL, function() { var data = this.evaluate(getLinkDeckData); fs.write(save, data + '\n', 'w'); }); 这样的东西。并且documentation about HTML arrays并没有真正说明当不可解析的字段名称进入时会发生什么。

当我们将其推向极限时会发生什么?显然,行为是不同的取决于我们谈论的超全球。在myModels[postedFiles[0]]中,PHP尽力创建数组:

$_POST
<input name="good[array][0]" type="text">
<input name="myModels[children[0]]" type="text">

但是,在array(2) { ["good"]=> array(1) { ["array"]=> array(1) { [0]=> string(0) "" } } ["myModels"]=> array(1) { ["children[0"]=> string(0) "" } } 中,数组中省略了无效字段:

$_FILES
<input name="good[file][0]" type="file">
<input name="myModels[postedFiles[0]]" type="file">

由于我们试图获得一个物理上不可能的结构,并且文档没有明确说明应该发生什么,我们处于未定义行为的领域:我们既不能投诉也不能依赖在它上面。

普通的帖子形式允许我们编写自己的解析器也是值得的:

array(1) {
  ["good"]=>
  array(5) {
    ["name"]=>
    array(1) {
      ["file"]=>
      array(1) {
        [0]=>
        string(0) ""
      }
    }
    ["type"]=>
    array(1) {
      ["file"]=>
      array(1) {
        [0]=>
        string(0) ""
      }
    }
    ["tmp_name"]=>
    array(1) {
      ["file"]=>
      array(1) {
        [0]=>
        string(0) ""
      }
    }
    ["error"]=>
    array(1) {
      ["file"]=>
      array(1) {
        [0]=>
        int(4)
      }
    }
    ["size"]=>
    array(1) {
      ["file"]=>
      array(1) {
        [0]=>
        int(0)
      }
    }
  }
}
var_dump(file_get_contents('php://input'));

...但不是multipart / form-data(aka files)。

为什么会出现这种明显的差异?我的猜测是,这是由于string(111) "good%5Barray%5D%5B0%5D=&myModels%5Bchildren%5B0%5D%5D=&good%5Bfile%5D%5B0%5D=&myModels%5BpostedFiles%5B0%5D%5D=" 超全球的特殊结构(恕我直言,错误设计为时已晚,无法解决)。使用简单名称时,您会在每个叶子的顶部获得五个自动键:

$_FILES

只要使用方括号,结构就会完全改变:

Array
(
    [one] => Array
        (
            [name] => 
            [type] => 
            [tmp_name] => 
            [error] => 4
            [size] => 0
        )

    [two] => Array
        (
            [name] => 
            [type] => 
            [tmp_name] => 
            [error] => 4
            [size] => 0
        )
)

这表明Array ( [one] => Array ( [name] => Array ( [0] => ) [type] => Array ( [0] => ) [tmp_name] => Array ( [0] => ) [error] => Array ( [0] => 4 ) [size] => Array ( [0] => 0 ) ) [two] => Array ( [name] => Array ( [0] => ) [type] => Array ( [0] => ) [tmp_name] => Array ( [0] => ) [error] => Array ( [0] => 4 ) [size] => Array ( [0] => 0 ) ) ) $_POST中的内部逻辑完全不同,因此在无效输入上看到不同的变通方法并不奇怪。

答案 1 :(得分:0)

我尝试制作相同的表格,但稍作修改。

<form action="uploadTest.php" method="post" enctype="multipart/form-data" >
    File1 <input name="myModels[postedFiles(0)]" type="file" /></br>
    File2 <input name="myModels[postedFiles(1)]" type="file" /></br>
    <input type="submit" value="post" />
</form> 
尝试上传文件时

print_r($ _ FILES)结果:

Array ( [myModels] => Array ( [name] => Array ( [postedFiles(0)] => file1.txt [postedFiles(1)] => file2.txt ) [type] => Array ( [postedFiles(0)] => text/plain [postedFiles(1)] => text/plain ) [tmp_name] => Array ( [postedFiles(0)] => /tmp/phpiHJBb1 [postedFiles(1)] => /tmp/phpSFh4J0 ) [error] => Array ( [postedFiles(0)] => 0 [postedFiles(1)] => 0 ) [size] => Array ( [postedFiles(0)] => 4 [postedFiles(1)] => 4 ) ) )

请参阅PHP手册: https://secure.php.net/manual/en/features.file-upload.post-method.php 查看示例#3以上传文件数组。

如果文件太大而无法通过upload_max_filesize或甚至post_max_size在php.ini中指定,那么这似乎不起作用。