PHP - 从不同的输入字段获取文件,但到同一个 arrray

PHP - Take file from different input fields, but to the same arrray

提问人:mbattaloglu 提问时间:9/7/2023 最后编辑:mbattaloglu 更新时间:9/7/2023 访问量:66

问:

我正在为房地产中介设计一个网站,在我的表格中,我正在拍摄几个“平面图”。

在表单中,有一个“添加平面图按钮”,此按钮广告用于拍摄平面图的输入字段(平面图的 1 张图像和 1 个名称)

这是形式(不介意元素):<form>

<div class="floorPlan">
        <label for="floorPlanPhoto" class="form-label">Floor Plan Photo</label>
        <input type="file" name="floorPlanPhoto[]" id="floorPlanPhoto" class="form-control" required>
        <label for="floorPlanName" class="form-label mt-1 mb-1">Kat Plan Name</label>
        <input type="text" name="floorPlanName" id="floorPlanName" class="form-control" required>
</div>

正如我之前提到的,用户可以添加多个平面图。因此,在我的中,可以有 1 个以上的输入字段用于添加平面图。<div class="floorPlans"></div>

如果用户仅添加 1 个平面图并提交表单,则会根据需要保存平面图(照片被保存并重命名为平面图名称)。但是,如果用户添加 2 个或更多计划,则仅保存最后一个计划。

当用户提交时,该字段被重写,我认为不是附加的。这可能是原因。所以我应该保存成多张照片floorPlanPhoto[]floorPlanPhoto[]

我该怎么做,或者用任何其他算法来做到这一点?

PS:我不想在输入字段中拍摄多个(我的意思是一个带有多个标签的输入区域)图像。用户应尽可能多地添加平面图(1 张图片和 1 个名称)。

这是保存文件的代码:

if(isset($_FILES["floorPlanPhoto"])){
    $images = $_FILES["floorPlanPhoto"];
    $imagesCount = count($images["name"]);
    $floorPlanName = $_POST["floorPlanName"];
    
    if (!file_exists("projects/" . $projectlink . "/floorplans")) {
        mkdir("projects/" . $projectlink . "/floorplans");
    }
    
    for ($i = 0; $i < $imagesCount; $i++) {
        $targetDir = "projects/" . $projectlink . "/floorplans/";
        $targetFile = $targetDir . basename($_FILES["floorPlanPhoto"]["name"][$i]);
        $uploadOk = 1;
        $imageFileType = strtolower(pathinfo($targetFile, PATHINFO_EXTENSION));
    
        //Check if the image file is actually image or fake image
        $check = getimagesize($_FILES["floorPlanPhoto"]["tmp_name"][$i]);
        if ($check !== false) {
            $uploadOk = 1;
        } else {
            $uploadOk = 0;
        }
    
        if ($uploadOk == 0) {
            $errors["imageError"] = "Error ";
        } else {
            if (move_uploaded_file($_FILES["floorPlanPhoto"]["tmp_name"][$i], $targetFile)) {
                $errors["imageSuccess"] = "Success!";
                rename($targetFile, $targetDir . $floorPlanName . ".jpg");
            } else {
                $errors["imageError"] = "Error.";
            }
        }
    
        print_r($errors);
    }

GIF - 添加平面图字段(如您所见,用户单击按钮,新字段将添加到页面中。以便用户可以提交计划的图像及其名称。enter image description here

var_dump[$_FILES](提交2张平面图时)

array(2) { 
    ["projectImages"]=> array(6) { 
        ["name"]=> array(2) { 
            [0]=> string(5) "2.jpg" 
            [1]=> string(5) "3.jpg" 
        } 
        ["full_path"]=> array(2) { 
            [0]=> string(5) "2.jpg" 
            [1]=> string(5) "3.jpg" 
        } 
        ["type"]=> array(2) { 
            [0]=> string(10) "image/jpeg" 
            [1]=> string(10) "image/jpeg" 
        } 
        ["tmp_name"]=> array(2) { 
            [0]=> string(24) "C:\xampp\tmp\phpE5A1.tmp" 
            [1]=> string(24) "C:\xampp\tmp\phpE5B2.tmp" 
        } 
        ["error"]=> array(2) { 
            [0]=> int(0) 
            [1]=> int(0) 
        } 
        ["size"]=> array(2) { 
            [0]=> int(390388) 
            [1]=> int(231082) 
        } 
    } 
    ["floorPlanPhoto"]=> array(6) { 
        ["name"]=> array(2) { 
            [0]=> string(8) "plan.jpg" 
            [1]=> string(9) "plan2.jpg" 
        } 
        ["full_path"]=> array(2) { 
            [0]=> string(8) "plan.jpg" 
            [1]=> string(9) "plan2.jpg" 
        } 
        ["type"]=> array(2) { 
            [0]=> string(10) "image/jpeg" 
            [1]=> string(10) "image/jpeg" 
        } 
        ["tmp_name"]=> array(2) { 
            [0]=> string(24) "C:\xampp\tmp\phpE5B3.tmp" 
            [1]=> string(24) "C:\xampp\tmp\phpE5B4.tmp" 
        } 
        ["error"]=> array(2) { 
            [0]=> int(0) 
            [1]=> int(0) 
        } 
        ["size"]=> array(2) { 
            [0]=> int(53386) 
            [1]=> int(58397) 
        } 
    }
} 

array(2) { 
    ["projectImages"]=> array(6) { 
        ["name"]=> array(2) { 
            [0]=> string(5) "2.jpg" 
            [1]=> string(5) "3.jpg" 
        } 
        ["full_path"]=> array(2) { 
            [0]=> string(5) "2.jpg" 
            [1]=> string(5) "3.jpg" 
        } 
        ["type"]=> array(2) { 
            [0]=> string(10) "image/jpeg" 
            [1]=> string(10) "image/jpeg" 
        } 
        ["tmp_name"]=> array(2) { 
            [0]=> string(24) "C:\xampp\tmp\phpE5A1.tmp" 
            [1]=> string(24) "C:\xampp\tmp\phpE5B2.tmp" 
        } 
        ["error"]=> array(2) { 
            [0]=> int(0) 
            [1]=> int(0) 
        } 
        ["size"]=> array(2) { 
            [0]=> int(390388) 
            [1]=> int(231082) 
        } 
    } 
    ["floorPlanPhoto"]=> array(6) { 
        ["name"]=> array(2) { 
            [0]=> string(8) "plan.jpg" 
            [1]=> string(9) "plan2.jpg" 
        } 
        ["full_path"]=> array(2) { 
            [0]=> string(8) "plan.jpg" 
            [1]=> string(9) "plan2.jpg" 
        } 
        ["type"]=> array(2) { 
            [0]=> string(10) "image/jpeg" 
            [1]=> string(10) "image/jpeg" 
        } 
        ["tmp_name"]=> array(2) { 
            [0]=> string(24) "C:\xampp\tmp\phpE5B3.tmp" 
            [1]=> string(24) "C:\xampp\tmp\phpE5B4.tmp" 
        } 
        ["error"]=> array(2) { 
            [0]=> int(0) 
            [1]=> int(0) 
        } 
        ["size"]=> array(2) { 
            [0]=> int(53386) 
            [1]=> int(58397) 
        } 
    } 
}

JavaScript 代码适用于 Button 单击以添加平面图的输入字段:

var floorPlanField = `
        <label for="floorPlanPhoto" class="form-label">Kat Planı Fotoğrafı</label>
        <input type="file" name="floorPlanPhoto[]" id="floorPlanPhoto" class="form-control" required>
        <label for="floorPlanName" class="form-label mt-1 mb-1">Kat Planı İsmi</label>
        <input type="text" name="floorPlanName" id="floorPlanName" class="form-control" required>
        <button class="btn btn-danger mt-1 mb-1 removeFloorPlanArea">Kaldır</button>`;

var addFloorPlanButton = document.getElementById("addFloorPlan");
var floorPlans = document.getElementsByClassName("floorPlans")[0];

addFloorPlanButton.addEventListener("click", addFloorPlan);

function addFloorPlan() {
    var floorPlan = document.createElement("div");
    floorPlan.classList.add("floorPlan");
    floorPlan.innerHTML = floorPlanField;
    var created = floorPlans.appendChild(floorPlan);
}
javascript php html 表单 dom

评论

1赞 RiggsFolly 9/7/2023
用户可以添加多个平面图。因此,在我的 <div class=“floorPlans”></div> 中,可以有 1 个以上的输入字段用于添加平面图。 那么,为什么不在示例代码中向我们展示您的意思
1赞 brombeer 9/7/2023
如果输入重复,你最终会得到多个相同的 s - 这是无效的,s 必须是唯一的。<div class="floorPlan">idid
1赞 RiggsFolly 9/7/2023
如果您要花几分钟时间阅读 PHP 文件上传文档,您将了解如何使用 $_FILES 数组来查找 1) 文件是否已成功上传 2) 上传文件的大小 3) 错误字段和有关每个错误代码含义的信息。等等而不是重新发明轮子并使其不那么完美
2赞 RiggsFolly 9/7/2023
你也可以考虑旧的前提,如果我需要其他人的帮助,我至少能做的就是花点时间确保我提供的数据至少是可读
1赞 RiggsFolly 9/7/2023
你的 JS 正在创建 Always 与 PHP 后端相同,因此只有一个返回到 PHP 后端<input type="text" name="floorPlanName" .....name="floorPlanName"

答:

0赞 mbattaloglu 9/7/2023 #1

问题是

@RiggisFolly : “除了你的所有文件都将被调用相同,因为你只会有一个 name=”floorPlanName“ 返回到后端”

因此,我修改了 JavaScript 代码以使名称不同

//first approach, it WORKS
var addFloorPlanButton = document.getElementById("addFloorPlan");
var floorPlans = document.getElementsByClassName("floorPlans")[0];

addFloorPlanButton.addEventListener("click", addFloorPlan);

let totalFloorPlan = 1;

function addFloorPlan() {
  var floorPlan = document.createElement("div");
  floorPlan.classList.add("floorPlan");
  floorPlan.innerHTML = createInputField(`floorPlanName${totalFloorPlan}`);
  totalFloorPlan++;
  var created = floorPlans.appendChild(floorPlan);
  var removeFloorPlanButton = created.getElementsByClassName("removeFloorPlanArea")[0];
  removeFloorPlanButton.addEventListener("click", removeFloorPlan);
}

function createInputField(name) {
  var floorPlanField = `
        <label for="floorPlanPhoto" class="form-label">Kat Planı Fotoğrafı</label>
        <input type="file" name="floorPlanPhoto[]" class="form-control" required>
        <label for="floorPlanName" class="form-label mt-1 mb-1">Kat Planı İsmi</label>
        <input type="text" name="${name}" class="form-control" required>
        <button class="btn btn-danger mt-1 mb-1 removeFloorPlanArea">Kaldır</button>
    `;
  return floorPlanField;

而且,后端对我的文件处理程序进行了迷你更新:

if(isset($_FILES["floorPlanPhoto"])){
            $images = $_FILES["floorPlanPhoto"];
            $imagesCount = count($images["name"]);
            
            if (!file_exists("projects/" . $projectlink . "/floorplans")) {
                mkdir("projects/" . $projectlink . "/floorplans");
            }
            
            for ($i = 0; $i < $imagesCount; $i++) {
                $floorPlanName = $_POST["floorPlanName" . $i+1]; //Take the plan name for every file -change is here-
                $targetDir = "projects/" . $projectlink . "/floorplans/";
                $targetFile = $targetDir . basename($_FILES["floorPlanPhoto"]["name"][$i]);
                $uploadOk = 1;
                $imageFileType = strtolower(pathinfo($targetFile, PATHINFO_EXTENSION));

                $check = getimagesize($_FILES["floorPlanPhoto"]["tmp_name"][$i]);
                if ($check !== false) {
                    $uploadOk = 1;
                } else {
                    $uploadOk = 0;
                }

                if ($uploadOk == 0) {
                    $errors["imageError"] = "Error";
                } else {
                    if (move_uploaded_file($_FILES["floorPlanPhoto"]["tmp_name"][$i], $targetFile)) {
                        $errors["imageSuccess"] = "Success";
                        rename($targetFile, $targetDir . $floorPlanName . ".jpg");
                    } else {
                        $errors["imageError"] = "Error.";
                    }
                }
            }
        }

这需要每一个图像和名称,并在后端进行操作。