我正在PHP中实现一个多用途html表单发布代码,能够发布对象图结构。
所以我创建了一些命名规则并基于它们,我在服务器端解析索引。
其中一条规则是这样的:
<input name="myModels[children[0]]" type="text" />
当然,上面的命名有点缩短,以便轻松达到目的。
当我从
中检索它时,该命名工作正常$ _ POST
但是当我在文件输入中使用它时,它们永远不会出现在$ _FILE全局数组中 和
print_r($_FILES);
为空
即使有文件,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。
答案 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中指定,那么这似乎不起作用。