Ben*_*Ben 19 php foreach loops input form-processing
以下是我想要循环的输入
Main photo: <input type="file" name="image[]" />
Side photo 1: <input type="file" name="image[]" />
Side photo 2: <input type="file" name="image[]" />
Side photo 3: <input type="file" name="image[]" />
Run Code Online (Sandbox Code Playgroud)
发生了一些奇怪的事情,当我上传任何我使用的东西时 count($_FILES['image']),我回显了该函数,并返回值5.该数组中应该没有元素.当我只有4个文件开始时,为什么还有一个额外的输入?
现在实际循环,我尝试使用foreach循环,但它不起作用.
foreach($_FILES['image'] as $files){echo $files['name']; }
Run Code Online (Sandbox Code Playgroud)
什么都没有出现,我想最终做的是遍历所有图像,确保它们是正确的格式,大小,并重命名它们.但是这个简单的foreach()循环显示,我甚至无法循环遍历$ _FILES数组,并且当我甚至没有上传任何内容时,当它说数组中有5个元素时,count()会让我更加困惑.
Dec*_*ler 42
您的示例表单应该可以正常工作 $_FILES当使用字段名称的数组结构时,只是期望超全局的结构与实际不同.
这个多维数组的结构如下:
$_FILES[fieldname] => array(
[name] => array( /* these arrays are the size you expect */ )
[type] => array( /* these arrays are the size you expect */ )
[tmp_name] => array( /* these arrays are the size you expect */ )
[error] => array( /* these arrays are the size you expect */ )
[size] => array( /* these arrays are the size you expect */ )
);
Run Code Online (Sandbox Code Playgroud)
因此count( $_FILES[ "fieldname" ] )会产生5.
但计算更深的尺寸也不会产生您可能期望的结果.count( $_FILES[ "fieldname" ][ "tmp_name" ] )例如,使用计数字段将始终产生文件字段的数量,而不是实际上载的文件数量.您仍然需要遍历元素以确定是否已为特定文件字段上载了任何内容.
编辑
所以,要遍历字段,您将执行以下操作:
// !empty( $_FILES ) is an extra safety precaution
// in case the form's enctype="multipart/form-data" attribute is missing
// or in case your form doesn't have any file field elements
if( strtolower( $_SERVER[ 'REQUEST_METHOD' ] ) == 'post' && !empty( $_FILES ) )
{
foreach( $_FILES[ 'image' ][ 'tmp_name' ] as $index => $tmpName )
{
if( !empty( $_FILES[ 'image' ][ 'error' ][ $index ] ) )
{
// some error occured with the file in index $index
// yield an error here
return false; // return false also immediately perhaps??
}
/*
edit: the following is not necessary actually as it is now
defined in the foreach statement ($index => $tmpName)
// extract the temporary location
$tmpName = $_FILES[ 'image' ][ 'tmp_name' ][ $index ];
*/
// check whether it's not empty, and whether it indeed is an uploaded file
if( !empty( $tmpName ) && is_uploaded_file( $tmpName ) )
{
// the path to the actual uploaded file is in $_FILES[ 'image' ][ 'tmp_name' ][ $index ]
// do something with it:
move_uploaded_file( $tmpName, $someDestinationPath ); // move to new location perhaps?
}
}
}
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参阅文档.
You*_*nse 10
只需这样重命名你的字段
Main photo: <input type="file" name="image1" />
Side photo 1: <input type="file" name="image2" />
Side photo 2: <input type="file" name="image3" />
Side photo 3: <input type="file" name="image4" />
Run Code Online (Sandbox Code Playgroud)
然后你就可以通常的方式迭代它:
foreach($_FILES as $file){
echo $file['name'];
}
Run Code Online (Sandbox Code Playgroud)
小智 8
将$ _FILES ['files']重建为更多预期结构的简短函数.
function restructureFilesArray($files)
{
$output = [];
foreach ($files as $attrName => $valuesArray) {
foreach ($valuesArray as $key => $value) {
$output[$key][$attrName] = $value;
}
}
return $output;
}
Run Code Online (Sandbox Code Playgroud)
我想出了一个适用于任意深度的 $_FILES 数组的解决方案。作为快速解释,您需要一个执行此操作的算法:
For each subtree in the file tree that's more than one item deep:
For each leaf of the subtree:
$leaf[a][b][c] ... [y][z] -> $result[z][a][b][c] ... [y]
Run Code Online (Sandbox Code Playgroud)
这是一些实际有效的代码。
function sane_file_array($files) {
$result = array();
$name = array();
$type = array();
$tmp_name = array();
$error = array();
$size = array();
foreach($files as $field => $data) {
foreach($data as $key => $val) {
$result[$field] = array();
if(!is_array($val)) {
$result[$field] = $data;
} else {
$res = array();
files_flip($res, array(), $data);
$result[$field] += $res;
}
}
}
return $result;
}
function array_merge_recursive2($paArray1, $paArray2) {
if (!is_array($paArray1) or !is_array($paArray2)) { return $paArray2; }
foreach ($paArray2 AS $sKey2 => $sValue2) {
$paArray1[$sKey2] = array_merge_recursive2(@$paArray1[$sKey2], $sValue2);
}
return $paArray1;
}
function files_flip(&$result, $keys, $value) {
if(is_array($value)) {
foreach($value as $k => $v) {
$newkeys = $keys;
array_push($newkeys, $k);
files_flip($result, $newkeys, $v);
}
} else {
$res = $value;
// Move the innermost key to the outer spot
$first = array_shift($keys);
array_push($keys, $first);
foreach(array_reverse($keys) as $k) {
// You might think we'd say $res[$k] = $res, but $res starts out not as an array
$res = array($k => $res);
}
$result = array_merge_recursive2($result, $res);
}
}
Run Code Online (Sandbox Code Playgroud)
只需对 $_FILES 调用 sane_files_array 就可以了,无论 $_FILES 数组有多深。这确实应该是语言本身的一部分,因为 $_FILES 数组的格式绝对是荒谬的。