php 在一个数据库表中的一行中上载多个图像

qjp7pelc  于 2023-04-04  发布在  PHP
关注(0)|答案(2)|浏览(135)

我想上传多个图像在一个单一的列。
在我的PHP表单中,我有一个输入名称,上传图像按钮和提交。
我有一个名为my_images的数据库表,其中包含id、name和image_data列。
在我的表单中,我输入了一个名称,我想上传多个图像,并只将其插入到数据库my_image表上传图像表单中的一行中:

<h2>Upload Images</h2>
    <form method="post" enctype="multipart/form-data">
        <label for="name">Name:</label>
        <input type="text" name="name" id="name"><br><br>
        <label for="images[]">Images:</label>
        <input type="file" name="images[]" id="images" multiple><br><br>
        <input type="submit" value="Upload">
    </form>

  <?php

// Check if the form was submitted
if ($_SERVER["REQUEST_METHOD"] == "POST") {

  // Get the name entered by the user
  $name = $_POST["name"];

  // Initialize an array to hold the image data
  $image_data_array = array();

  // Loop through each uploaded image
  foreach ($_FILES["images"]["tmp_name"] as $key => $tmp_name) {

    // Check if the image was uploaded successfully
    if ($_FILES["images"]["error"][$key] == UPLOAD_ERR_OK) {

      // Read the contents of the image file
      $image_data = file_get_contents($tmp_name);

      // Add the image data to the array
      $image_data_array[] = $image_data;

    } else {

      echo "Error uploading image: " . $_FILES["images"]["error"][$key];
    }
  }

  // Combine the image data into a single binary string
  $combined_image_data = implode("", $image_data_array);

  $stmt = mysqli_prepare($conn, "INSERT INTO my_images (name, image_data) VALUES (?, ?)");
  mysqli_stmt_bind_param($stmt, "sb", $name, $combined_image_data);
  mysqli_stmt_execute($stmt);

  echo "Images uploaded successfully!";
}

?>

我试过将图像数据组合成一个二进制字符串并将其存储在BLOB列中,但这只能将图像放在多个列中。
当我提交多个图像时,我不想为我的图像数据库文件创建多个输入字段:

为什么我想这样做的原因是因为在我的网站我想显示容器的名称和多个图像container with images

5cg8jx4n

5cg8jx4n1#

你想把所有的图片放在一个列中,这是可以做到的,但这可能不是最好的做法。
也许我建议,上传图像到一个文件夹。然后你可以连接图像的路径到一个字符串,并把它放在一列。
然后你必须解构这个字符串来给予你到图像的各个路径,然后你将把这些路径馈送到html中,这样你就可以根据需要显示图像了。
您也可以只为图像和用户创建一个表
然后创建它们之间的关系以识别哪些图像属于哪个用户。
这些方法将是更少的CPU密集型和更少的复杂性,然后你提出的方法。

toiithl6

toiithl62#

这是可能的,但我不推荐这种方法。
首先,我指出数据类型最好用字符串表示,所以:

mysqli_stmt_bind_param($stmt, "sb", $name, $combined_image_data);

应为:

mysqli_stmt_bind_param($stmt, 'ss', $name, $combined_image_data);

因此,要检索单个图像,您必须将它们的数量和大小保存在某个地方。要实现这一点,您可以这样做:

if ($_FILES["images"]["error"][$key] == UPLOAD_ERR_OK)
{
    $image_data = file_get_contents($tmp_name);
    $size = strlen($image_data);

    // temporarily stores each size and each image data
    $image_data_array[] = [$size, $image_data];
}
else
{
    /* */
}

然后,您需要在图像数据之前在blob中存储头部:

// the number of images
    $blob = str_pad(count($image_data_array), 4, '0', STR_PAD_LEFT);

    // the sizes (adjust the number of digits as your needings, here is 12)
    foreach ($image_data_array as $imageData)
        $blob .= str_pad($imageData[0], 12, '0', STR_PAD_LEFT);

   // the images 
    foreach ($image_data_array as $imageData)
        $blob .= $imageData[1];

最后您可以存储数据

$stmt = mysqli_prepare /* ... */
mysqli_stmt_bind_param($stmt, 'ss', $name, $blob); 
mysqli_stmt_execute($stmt);

要检索图像,您必须阅读标题以了解要分割blob的图像的数量和大小:

// example of simple fetch, you should prepare etc...
$sql = 'SELECT * FROM my_images WHERE ...';
$result = mysqli_query ($conn, $sql);
$data = mysqli_fetch_assoc($result);

// 4 is the number of digits of the number of images
$nImages = (int)substr($data['image_data'], 0, 4);

// 12 is the number of digits of the images sizes
$imagesSizes = str_split(substr($data['image_data'], 4, $nImages * 12), 12);

$imagesOffset = 4 + $nImages * 12;

for ($n = 0; $n < $nImages; $n++)
{
    // extract an image from the blob
    $img = substr($data['image_data'], $imagesOffset, (int)$imagesSizes[$n]);

    // do what you want with your image stored in $img
    
    $imagesOffset += (int)$imagesSizes[$n];
}

但我建议创建两个表:第一个我们调用包含id和描述的父表,第二个包含每个图像的一行,其中包含任何细节以及父表的id:

CREATE TABLE `my_images` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
);

CREATE TABLE `my_images_details` (
  `id` int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `my_images_id` int(10) unsigned NOT NULL,
  `image_type` varchar(255) NOT NULL,
  `image` longblob NOT NULL,
  FOREIGN KEY (`my_images_id`) REFERENCES `my_images` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
);

这样,要检索图像,您可以选择 my_imagedetails.my_image _id 等于 myimages.id 的所有行,并且每行将包含一个图像

最后,我还建议您评估将图像存储在文件系统上并始终使用两个表的可能性,以便在子表中存储图像路径而不是其内容

相关问题