php,从多个输入上传多个文件
php, upload multiple files from multiple input
我有一个包含多行的表单(来自 SQL 的行,迭代并生成了表单)。
这些行中的每一行都有一个多文件输入字段(用户可以在每个输入中上传 0、1 或多个文件)。
文件正在正确上传,并正确分配了新文件名(文件名是根据每一行 SQL ID 生成的)。
然后在用户单击提交后,文件名将添加到 SQL table.
中的列
表单可以生成 0、1 ... 100 行,因此为了防止 php 遍历所有这 100 行,并在不需要的地方执行 UPDATE 或行,我只执行更新用户已触摸的行。
我的问题是当我在单个文件输入字段(一行)上上传单个或多个文件时,一切都按预期进行。
但是,当我尝试在单独的文件输入字段中上传 1 个或多个文件时,SQL 中发生了一些奇怪的事情,上传到服务器的文件都正常,但数据库变得奇怪。
- 第一个输入(行)将根据需要包含正确名称的正确文件数。
- 每个下一个输入(更新后数据库中的行)将包含所有先前输入的所有文件名,加上为特定输入上传的文件名...如果有意义...此处插图:
Input 1: input1file1.jpg, input1file2.jpg
Input 2: input1file1.jpg, input1file2.jpg, input2file1.jpg
因为每个输入框可以取多个文件,所以输入的名字已经是一个数组名='attachment[]'.
为了区分这些输入字段,我将行 ID 添加到文件名中。
这是我的代码,我不知道是什么原因造成的?
表格:
<form enctype="multipart/form-data" method="post">
...
php iteration:
<div>
<input class="hasChanged" name="attachments'.$row['pk'].'[]" type="file" multiple>
<input value="'.$row['existing_attachments'].'" id="updateAttachmentValue'.$row['pk'].'" name="existingAttachments'.$row['pk'].'">
</div>
...
</form>
PHP:
//iterate
foreach($_POST['foo_field'] as $key => $n){
if(in_array($upl[$key], $touched_rows)){
$aID = $upl[$key];
$prevAttachments = (empty($_POST['existingAttachments'.$aID]) || $_POST['existingAttachments'.$aID]=='|') ? NULL : $_POST['existingAttachments'.$aID];
$attachments = NULL;
if(count($_FILES['attachments'.$aID]['name']) > 0){
if(!empty($_FILES['attachments'.$aID])){
for($i=0; $i<count($_FILES['attachments'.$aID]['name']); $i++){//Loop through each file
$tmpFilePath = $_FILES['attachments'.$aID]['tmp_name'][$i];//Get the temp file path
if($tmpFilePath != ''){//Make sure we have a filepath
$shortname = 'AP-'.$aID.'-'.$_FILES['attachments'.$aID]['name'][$i];//save the filename
$filePath = $attachmentDirectory.'\AP-'.$aID.'-'.$_FILES['attachments'.$aID]['name'][$i];//save the url and the file
if(move_uploaded_file($tmpFilePath, $filePath)){//Upload the file into the correct dir
$files[] = $shortname;
}
$attachments = implode('|',$files);
}
}
}
}
$prevAttachments = !empty($attachments) ? $attachments.'|'.$prevAttachments : $prevAttachments;
try{
$stmt = $conn->prepare("EXEC [name].[dbo].[table] :p1,:p2");
$stmt->bindParam(':p1', $upl[$key], PDO::PARAM_INT);
$stmt->bindParam(':p2', $prevAttachments, PDO::PARAM_STR);
$stmt->execute();
}catch(PDOException $e){ echo 'ERROR: ' . $e->getMessage();}
}
}
在您的代码中,您从未设置或重置 $files
,因此该值包含所有以前的文件。
您应该在每个“行”的开头设置 $files = array();
以确保 $files
仅包含特定行的值。
我有一个包含多行的表单(来自 SQL 的行,迭代并生成了表单)。 这些行中的每一行都有一个多文件输入字段(用户可以在每个输入中上传 0、1 或多个文件)。 文件正在正确上传,并正确分配了新文件名(文件名是根据每一行 SQL ID 生成的)。 然后在用户单击提交后,文件名将添加到 SQL table.
中的列表单可以生成 0、1 ... 100 行,因此为了防止 php 遍历所有这 100 行,并在不需要的地方执行 UPDATE 或行,我只执行更新用户已触摸的行。
我的问题是当我在单个文件输入字段(一行)上上传单个或多个文件时,一切都按预期进行。 但是,当我尝试在单独的文件输入字段中上传 1 个或多个文件时,SQL 中发生了一些奇怪的事情,上传到服务器的文件都正常,但数据库变得奇怪。
- 第一个输入(行)将根据需要包含正确名称的正确文件数。
- 每个下一个输入(更新后数据库中的行)将包含所有先前输入的所有文件名,加上为特定输入上传的文件名...如果有意义...此处插图:
Input 1: input1file1.jpg, input1file2.jpg
Input 2: input1file1.jpg, input1file2.jpg, input2file1.jpg
因为每个输入框可以取多个文件,所以输入的名字已经是一个数组名='attachment[]'.
为了区分这些输入字段,我将行 ID 添加到文件名中。
这是我的代码,我不知道是什么原因造成的?
表格:
<form enctype="multipart/form-data" method="post">
...
php iteration:
<div>
<input class="hasChanged" name="attachments'.$row['pk'].'[]" type="file" multiple>
<input value="'.$row['existing_attachments'].'" id="updateAttachmentValue'.$row['pk'].'" name="existingAttachments'.$row['pk'].'">
</div>
...
</form>
PHP:
//iterate
foreach($_POST['foo_field'] as $key => $n){
if(in_array($upl[$key], $touched_rows)){
$aID = $upl[$key];
$prevAttachments = (empty($_POST['existingAttachments'.$aID]) || $_POST['existingAttachments'.$aID]=='|') ? NULL : $_POST['existingAttachments'.$aID];
$attachments = NULL;
if(count($_FILES['attachments'.$aID]['name']) > 0){
if(!empty($_FILES['attachments'.$aID])){
for($i=0; $i<count($_FILES['attachments'.$aID]['name']); $i++){//Loop through each file
$tmpFilePath = $_FILES['attachments'.$aID]['tmp_name'][$i];//Get the temp file path
if($tmpFilePath != ''){//Make sure we have a filepath
$shortname = 'AP-'.$aID.'-'.$_FILES['attachments'.$aID]['name'][$i];//save the filename
$filePath = $attachmentDirectory.'\AP-'.$aID.'-'.$_FILES['attachments'.$aID]['name'][$i];//save the url and the file
if(move_uploaded_file($tmpFilePath, $filePath)){//Upload the file into the correct dir
$files[] = $shortname;
}
$attachments = implode('|',$files);
}
}
}
}
$prevAttachments = !empty($attachments) ? $attachments.'|'.$prevAttachments : $prevAttachments;
try{
$stmt = $conn->prepare("EXEC [name].[dbo].[table] :p1,:p2");
$stmt->bindParam(':p1', $upl[$key], PDO::PARAM_INT);
$stmt->bindParam(':p2', $prevAttachments, PDO::PARAM_STR);
$stmt->execute();
}catch(PDOException $e){ echo 'ERROR: ' . $e->getMessage();}
}
}
在您的代码中,您从未设置或重置 $files
,因此该值包含所有以前的文件。
您应该在每个“行”的开头设置 $files = array();
以确保 $files
仅包含特定行的值。