以影响帖子数组的形式上传图像

Image upload in a form affecting the post array

提问人:HenryW-C 提问时间:11/4/2023 最后编辑:HenryW-C 更新时间:11/5/2023 访问量:47

问:

我有一个表格,就是将一本书添加到数据库中。当表单输入中不包含图像时,一切都可以完美运行,但是当包含图像时,会产生错误消息,但数据仍会输入到数据库中。

这是表单所在的网页:

<div class="list">
    <div class="row">
        <!-- first column with the title input then the image input -->
        <div class="col-md-4">
            <form action="upload.php" method="post" enctype="multipart/form-data">
                <input type="text" style="margin-bottom: 2vh; z-index:10;" class="list-features" name="title" placeholder="Type title here..." required>
                <input type="text" style="margin-bottom: 2vh; height: 6vh; font-size: 24px;" class="list-features" name="author" placeholder="Type author here..." >
                <div class="custom-column justify-content-center" style="height: 64vh;">
                    <!-- this creates a new button over the file input so that it can be styled -->
                    <div class="file-upload-container">
                        <label for="fileToUpload" class="file-upload-button">
                            <span class="file-upload-button-label">Select Image</span>
                        </label>
                        <input style="z-index:-5;" type="file" name="fileToUpload" id="fileToUpload" class="file-upload-input" onchange="previewImage()">
                        <br><br>
                        <!-- image preview -->
                        <img id="image-preview" src="">
                    </div>

                    <!-- script to preview the image -->
                    <script>
                        function previewImage() {
                            const fileInput = document.getElementById('fileToUpload');
                            const imagePreview = document.getElementById('image-preview');
                            const file = fileInput.files[0];
                            if (file) {
                                const reader = new FileReader();
                                reader.onload = function(e) {
                                    imagePreview.src = e.target.result;
                                };
                                reader.readAsDataURL(file);
                            } else {
                                imagePreview.src = ''; // clear the image if no file is selected
                            }
                        }
                    </script>
            </div>
        </div>

        <!-- second column with the description box then the price box -->
        <div class="col-md-4">
            <div class="custom-column" style="height: 72vh;">
                <textarea type="text" name="description" placeholder="Type description here..." style="border: none; height: 100%; text-align: left" required></textarea>
            </div>
            <input type="text" style="margin-top: 2vh;" class="list-features" name="price" placeholder="Type price here..." required>
        </div>

        <!-- third column with the category selection then the submit button -->
        <div class="col-md-4">
            <div class="custom-column justify-content-center" style="height: 72vh;">
                <select class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" name="selectedLevel"  style="margin-bottom: 100px;">
                    <!-- php code to take levels from table and display as dropdown options -->
                    <option selected disabled>Select Level</option>
                    <?php
                    include_once("connection.php");
                    $stmt = $conn->prepare('SELECT category FROM tblCategories WHERE categoryType = 0');
                    $stmt->execute();
                    $results = $stmt->fetchAll();

                    foreach ($results as $row): ?>
                        <option value="<?=$row["category"]?>"><?=$row["category"]?></option>
                    <?php endforeach ?>
                </select>
                
                <select class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" name="selectedSubject"  style="margin-top: 100px;">
                    <!-- php code to take subjects from table and display as dropdown options -->
                    <option selected disabled>Select Category</option>
                    <?php
                    include_once("connection.php");
                    $stmt = $conn->prepare('SELECT category FROM tblCategories WHERE categoryType = 1');
                    $stmt->execute();
                    $results = $stmt->fetchAll();

                    foreach ($results as $row): ?>
                        <option value="<?=$row["category"]?>"><?=$row["category"]?></option>
                    <?php endforeach ?>
                </select>
            </div>
            <!-- submit button for the full form -->
            <input type="submit" class="btn btn-primary btn-list" name="submit" value="List" style="width:100%;">
                </form>
        </div>
    </div>
</div>

这是处理数据的代码:

<?php
session_start(); 
$_POST = array_map("htmlspecialchars", $_POST);
include_once("connection.php");

echo "<pre>";
print_r($_POST);
echo "</pre>";

print_r($_SESSION);

$stmt = $conn->prepare("INSERT INTO 
  TblBooks (bookID, name, author, subject, level, description, image, price, sold, sellerID, buyerID, orderID)
  VALUES (null, :name, :author, :subject, :level, :description, null, :price, 0, :userID, null, null)");

  $stmt->bindParam(':name', $_POST["title"]);
  $stmt->bindParam(':author', $_POST["author"]);
  $stmt->bindParam(':subject', $_POST["selectedSubject"]);
  $stmt->bindParam(':level', $_POST["selectedLevel"]);
  $stmt->bindParam(':description', $_POST["description"]);
  $stmt->bindParam(':price', $_POST["price"]);
  $stmt->bindParam(':userID', $_SESSION['UserID']);
  $stmt->execute();

if (isset($_FILES["fileToUpload"]) && $_FILES["fileToUpload"]["error"] === 0) {
  // if an image was uploaded, specifies the filename for the image
  $filename = ($conn->lastInsertId());

  $target_dir = "/Applications/XAMPP/htdocs/bookshop/images/";
  $target_file = $target_dir . $filename . "." . strtolower(pathinfo($_FILES["fileToUpload"]["name"], PATHINFO_EXTENSION));
  $uploadOk = 1;
  $imageFileType = strtolower(pathinfo($target_file, PATHINFO_EXTENSION));

  // check file size
  if ($_FILES["fileToUpload"]["size"] > 500000) {
    echo "Sorry, your file is too large.";
    $uploadOk = 0;
  }

  // check if $uploadOk is set to 0 by an error
  if ($uploadOk == 0) {
    echo "Sorry, your file was not uploaded.";
  } else {
    if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
      echo "The file " . htmlspecialchars($filename) . " has been uploaded.";
      header('Location: ' . $backURL);
    } else {
      echo "Sorry, there was an error uploading your file.";
    }
  }

  // tblBooks is updated to list the new file name
  $stmt = $conn->prepare("UPDATE tblBooks SET image=:imageName WHERE bookID=:bookID");
  $stmt->bindParam(':imageName', $filename);
  $stmt->bindParam(':bookID', $conn->lastInsertId());
  $stmt->execute();
  $conn=null;
}
?>

我知道文件后缀的处理方式也存在一个错误,但我相信这与现在无关。

当表单条目中不包含图像时,输出将按预期进行:

Array
(
    [title] => Sample tite
    [author] => Sample author
    [description] => Sample descrition
    [price] => 8.50
    [selectedSubject] => Drama
    [submit] => List
)

Array ( [Email] => [email protected] [backURL] => /bookshop/list.php )

但是,当包含图像时,会产生以下错误:

Array
(
)

Array ( [Email] => [email protected] [backURL] => /bookshop/list.php )
Fatal error: Uncaught PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'name' cannot be null in /Applications/XAMPP/xamppfiles/htdocs/bookshop/upload.php:23 Stack trace: #0 /Applications/XAMPP/xamppfiles/htdocs/bookshop/upload.php(23): PDOStatement->execute() #1 {main} thrown in /Applications/XAMPP/xamppfiles/htdocs/bookshop/upload.php on line 23

提前致谢!

PHP HTML 表单

评论

0赞 Markus Zeller 11/4/2023
看起来 $_POST 数组是空的。如果该名称字段为 null,则 DDL 中不允许这样做。
0赞 Nigel Ren 11/4/2023
不确定是不是一个好主意。$_POST = array_map("htmlspecialchars", $_POST);
0赞 KIKO Software 11/4/2023
你可以试着不使用,看看它有什么帮助吗?通过简化事情进行调试。在你的问题中显然没有意义的是,它看起来像是空的,但你说一切都被输入到数据库中。这没有意义。previewImage()$_POST
0赞 HenryW-C 11/4/2023
@KIKOSoftware我已经尝试删除该部分和代码的其他部分,只要有通过表单发送的图像,问题仍然存在。是的,它仍在输入数据库的事实更令人困惑,[链接到错误](imgur.com/a/Y9QOSKQ),[链接到数据库](imgur.com/a/wqhI0kz)
0赞 TSCAmerica.com 11/5/2023
该问题可能与表单的 enctype 属性有关。使用 enctype=“multipart/form-data” 时,表单数据以不同的格式发送,这对于文件上传是必需的,但有时可能会导致检索其他表单数据时出现问题。您看到的错误消息指示数据库中的“name”列不能为 null,但传递的是 null 值。发生这种情况是因为当您提交包含图像的表单时,$_POST 数组为空。造成这种情况的原因可能是由于您处理表单提交的方式。

答: 暂无答案