PHP 循环上传多张图片
PHP Upload Multiple Images through Loop
我正在尝试循环上传多张图片,但出于某种原因,它会创建目录、上传 1 个文件并创建 MySQL 记录,所以我不确定为什么它甚至只上传 1 个文件虽然当我打印 $i 以查看已计算了多少文件时,它总是计算正确的数量。
PHP
function generateRandomString($length = 25) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
if (isset($_POST['newYoungSubmit'])) {
$imageDirectory = "images/youngMembers";
$newDirName = generateRandomString(20);
$postDate = date("Y-m-d");
$targetDir = $imageDirectory."/".$newDirName."/";
if (!file_exists($targetDir)) {
mkdir($targetDir, 0777, true);
} else {
$newDirName = generateRandomString(20);
$targetDir = $imageDirectory."/".$newDirName."/";
}
// Count total files
$fileCount = count($_FILES['new_young']['name']);
// Iterate through the files
for($i = 0; $i < $fileCount; $i++){
$target_dir = $imageDirectory."/".$newDirName."/";
$target_file = $target_dir . basename($_FILES["new_young"]["name"][$i]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
// Check if image file is a actual image or fake image
$check = getimagesize($_FILES["new_young"]["tmp_name"][$i]);
if($check !== false) {
//echo "File is an image - " . $check["mime"] . ".";
$uploadOk = 1;
} else {
$errorTxt = "File is not an image.";
$uploadOk = 0;
}
// Check if file already exists
if (file_exists($target_file)) {
$errorTxt = "Sorry, file already exists.";
$uploadOk = 0;
}
// Check file size
// if ($_FILES["new_young"]["size"] > 500000) {
// $errorTxt = "Sorry, your file is too large.";
// $uploadOk = 0;
// }
// Allow certain file formats
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
&& $imageFileType != "gif" ) {
$errorTxt = "Sorry, only JPG, JPEG, PNG & GIF files are allowed.";
$uploadOk = 0;
}
// Check if $uploadOk is set to 0 by an error
$temp = explode(".", $_FILES["new_young"]["name"][$i]);
$newfilename = round(microtime(true)) . '.' . end($temp);
if ($uploadOk == 0) {
// if everything is ok, try to upload file
} else {
if (move_uploaded_file($_FILES["new_young"]["tmp_name"][$i], $target_dir . $newfilename)) {
//echo "The file ". basename( $_FILES["new_young"]["name"]). " has been uploaded.";
} else {
$errorTxt = "Sorry, there was an error uploading your file.";
}
}
}
$newYoungQuery = $conn->prepare("INSERT INTO youngMembers (youngTitle, youngImgDir, youngDesc) VALUES (?,?,?)");
$newYoungQuery->execute([$_POST['youngTitle'], $targetDir, $_POST['youngDesc']]);
$newYoungQuery = null;
}
HTML
<form class="col s12" method="POST" action="" enctype="multipart/form-data">
<div class="row">
<div class="input-field col s12 m6">
<input name="youngTitle" id="youngTitle" required type="text" class="validate">
<label for="youngTitle">Title<span class="red-text">*</span></label>
</div>
<div class="file-field input-field col s12 m6">
<div class="btn">
<span>Image(s)</span>
<input name="new_young[]" type="file" multiple="multiple">
</div>
<div class="file-path-wrapper">
<input class="file-path validate" type="text">
</div>
</div>
</div>
<div class="row">
<div class="input-field col s12 m12">
<div class="input-field col s12 m12">
<textarea id="youngDesc" name="youngDesc" class="materialize-textarea" data-length="4096"></textarea>
<label for="youngDesc">Description</label>
</div>
</div>
</div>
<div class="row">
<div class="col s12 m3 offset-m9 input-field">
<input type="submit" class="white green-button-border black-text btn-large" name="newYoungSubmit">
</div>
</div>
</form>
我已经上传了 HTML 表单和 PHP 脚本,当提交表单时 运行,据我所知,我的脚本将检查表单已提交,生成一个随机字符串,它成为新目录名称,在我检查它是否已创建之后,如果没有创建新目录,然后我 运行 循环遍历并上传所有选定的图像到该目录,最后我将数据上传到 MySQL table.
这个问题,我相信已经正确地检查了代码并对其进行了测试,因为文件正在使用新名称保存并且新名称是使用以下方式生成的:
$newfilename = round( microtime(true) ) . '.' . end($temp);
当我在 3 个文件上传中对此进行测试时,我在添加一些调试语句时观察到以下内容。
..OK
1630745144.jpg - OK
..OK
1630745144.jpg - OK
..OK
1630745144.jpg - OK
所有三个都分配了相同的名称,因此只有最后一个似乎已上传,因为其他两个已被覆盖。
提到的调试是:
$newfilename = round( microtime(true) ) . '.' . end($temp);
if ($uploadOk == 0) {
echo $errorTxt;
} else {
if (move_uploaded_file($_FILES["new_young"]["tmp_name"][$i], $target_dir . $newfilename)) {
echo '..OK<br />';
} else {
$errorTxt = "Sorry, there was an error uploading your file.";
}
echo $newfilename . ' - OK<br />';
}
人们会假设这里的 $errorTxt
会声明文件已经存在,但事实并非如此,因为 $target_file
和 $newfilename
不相同。新名称应在 if (file_exists($target_file)) {
检查之前生成。
因此 - 如果您将原始文件中的相关代码更改为此,逻辑测试将起作用,但文件仍然无法上传。
$temp = explode(".", $_FILES["new_young"]["name"][$i]);
$newfilename = round( microtime(true) ) . '.' . end($temp);
$target_file = $target_dir . $newfilename;
if (file_exists($target_file)) {
$errorTxt = "Sorry, file already exists.";
$uploadOk = 0;
}
if ($uploadOk == 0) {
// if everything is ok, try to upload file
echo $errorTxt;
} else {
if (move_uploaded_file($_FILES["new_young"]["tmp_name"][$i], $target_file )) {
//echo "The file ". basename( $_FILES["new_young"]["name"]). " has been uploaded.";
} else {
$errorTxt = "Sorry, there was an error uploading your file.";
}
}
现在的问题是 $newfilename = round( microtime(true) )
将生成相同的整数 - 一个很大但相同的整数。从微时间派生的精度丢失,因此您可以将其修改为:
$newfilename = str_replace( '.', '', strval( microtime( true ) ) ) . '.' . end( $temp );
完成后,您的代码应该一切正常 - 上传三张图片正常。
我正在尝试循环上传多张图片,但出于某种原因,它会创建目录、上传 1 个文件并创建 MySQL 记录,所以我不确定为什么它甚至只上传 1 个文件虽然当我打印 $i 以查看已计算了多少文件时,它总是计算正确的数量。
PHP
function generateRandomString($length = 25) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
if (isset($_POST['newYoungSubmit'])) {
$imageDirectory = "images/youngMembers";
$newDirName = generateRandomString(20);
$postDate = date("Y-m-d");
$targetDir = $imageDirectory."/".$newDirName."/";
if (!file_exists($targetDir)) {
mkdir($targetDir, 0777, true);
} else {
$newDirName = generateRandomString(20);
$targetDir = $imageDirectory."/".$newDirName."/";
}
// Count total files
$fileCount = count($_FILES['new_young']['name']);
// Iterate through the files
for($i = 0; $i < $fileCount; $i++){
$target_dir = $imageDirectory."/".$newDirName."/";
$target_file = $target_dir . basename($_FILES["new_young"]["name"][$i]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
// Check if image file is a actual image or fake image
$check = getimagesize($_FILES["new_young"]["tmp_name"][$i]);
if($check !== false) {
//echo "File is an image - " . $check["mime"] . ".";
$uploadOk = 1;
} else {
$errorTxt = "File is not an image.";
$uploadOk = 0;
}
// Check if file already exists
if (file_exists($target_file)) {
$errorTxt = "Sorry, file already exists.";
$uploadOk = 0;
}
// Check file size
// if ($_FILES["new_young"]["size"] > 500000) {
// $errorTxt = "Sorry, your file is too large.";
// $uploadOk = 0;
// }
// Allow certain file formats
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
&& $imageFileType != "gif" ) {
$errorTxt = "Sorry, only JPG, JPEG, PNG & GIF files are allowed.";
$uploadOk = 0;
}
// Check if $uploadOk is set to 0 by an error
$temp = explode(".", $_FILES["new_young"]["name"][$i]);
$newfilename = round(microtime(true)) . '.' . end($temp);
if ($uploadOk == 0) {
// if everything is ok, try to upload file
} else {
if (move_uploaded_file($_FILES["new_young"]["tmp_name"][$i], $target_dir . $newfilename)) {
//echo "The file ". basename( $_FILES["new_young"]["name"]). " has been uploaded.";
} else {
$errorTxt = "Sorry, there was an error uploading your file.";
}
}
}
$newYoungQuery = $conn->prepare("INSERT INTO youngMembers (youngTitle, youngImgDir, youngDesc) VALUES (?,?,?)");
$newYoungQuery->execute([$_POST['youngTitle'], $targetDir, $_POST['youngDesc']]);
$newYoungQuery = null;
}
HTML
<form class="col s12" method="POST" action="" enctype="multipart/form-data">
<div class="row">
<div class="input-field col s12 m6">
<input name="youngTitle" id="youngTitle" required type="text" class="validate">
<label for="youngTitle">Title<span class="red-text">*</span></label>
</div>
<div class="file-field input-field col s12 m6">
<div class="btn">
<span>Image(s)</span>
<input name="new_young[]" type="file" multiple="multiple">
</div>
<div class="file-path-wrapper">
<input class="file-path validate" type="text">
</div>
</div>
</div>
<div class="row">
<div class="input-field col s12 m12">
<div class="input-field col s12 m12">
<textarea id="youngDesc" name="youngDesc" class="materialize-textarea" data-length="4096"></textarea>
<label for="youngDesc">Description</label>
</div>
</div>
</div>
<div class="row">
<div class="col s12 m3 offset-m9 input-field">
<input type="submit" class="white green-button-border black-text btn-large" name="newYoungSubmit">
</div>
</div>
</form>
我已经上传了 HTML 表单和 PHP 脚本,当提交表单时 运行,据我所知,我的脚本将检查表单已提交,生成一个随机字符串,它成为新目录名称,在我检查它是否已创建之后,如果没有创建新目录,然后我 运行 循环遍历并上传所有选定的图像到该目录,最后我将数据上传到 MySQL table.
这个问题,我相信已经正确地检查了代码并对其进行了测试,因为文件正在使用新名称保存并且新名称是使用以下方式生成的:
$newfilename = round( microtime(true) ) . '.' . end($temp);
当我在 3 个文件上传中对此进行测试时,我在添加一些调试语句时观察到以下内容。
..OK
1630745144.jpg - OK
..OK
1630745144.jpg - OK
..OK
1630745144.jpg - OK
所有三个都分配了相同的名称,因此只有最后一个似乎已上传,因为其他两个已被覆盖。
提到的调试是:
$newfilename = round( microtime(true) ) . '.' . end($temp);
if ($uploadOk == 0) {
echo $errorTxt;
} else {
if (move_uploaded_file($_FILES["new_young"]["tmp_name"][$i], $target_dir . $newfilename)) {
echo '..OK<br />';
} else {
$errorTxt = "Sorry, there was an error uploading your file.";
}
echo $newfilename . ' - OK<br />';
}
人们会假设这里的 $errorTxt
会声明文件已经存在,但事实并非如此,因为 $target_file
和 $newfilename
不相同。新名称应在 if (file_exists($target_file)) {
检查之前生成。
因此 - 如果您将原始文件中的相关代码更改为此,逻辑测试将起作用,但文件仍然无法上传。
$temp = explode(".", $_FILES["new_young"]["name"][$i]);
$newfilename = round( microtime(true) ) . '.' . end($temp);
$target_file = $target_dir . $newfilename;
if (file_exists($target_file)) {
$errorTxt = "Sorry, file already exists.";
$uploadOk = 0;
}
if ($uploadOk == 0) {
// if everything is ok, try to upload file
echo $errorTxt;
} else {
if (move_uploaded_file($_FILES["new_young"]["tmp_name"][$i], $target_file )) {
//echo "The file ". basename( $_FILES["new_young"]["name"]). " has been uploaded.";
} else {
$errorTxt = "Sorry, there was an error uploading your file.";
}
}
现在的问题是 $newfilename = round( microtime(true) )
将生成相同的整数 - 一个很大但相同的整数。从微时间派生的精度丢失,因此您可以将其修改为:
$newfilename = str_replace( '.', '', strval( microtime( true ) ) ) . '.' . end( $temp );
完成后,您的代码应该一切正常 - 上传三张图片正常。