简体   繁体   English

PHP mysql相册允许一张照片包含在多个相册中(数据库结构)

[英]PHP mysql photo album allow one photo to be in multiple albums (database structure)

I have two tables from a mysql database with the following schema: 我有一个具有以下架构的mysql数据库中的两个表:

albums: title, date_created, date_modified, albumID (primary key) photos: caption, image_url, date_taken, imageID (primary key) 相册:标题,创建日期,修改日期,相册ID(主键)照片:标题,图像网址,日期拍摄,图像ID(主键)

I am creating a php/mysql powered online photo album, and I would like to allow a photo to be on multiple albums, so I didn't put albumID in photos as a foreign key. 我正在创建一个由php / mysql驱动的在线相册,并且我希望允许一张照片包含在多个相册中,因此我没有将相册ID放在照片中作为外键。 The only way I can do this is to create a third table that relates the imageID to albumID, but so far I have failed to do this. 我这样做的唯一方法是创建第三个表,该表将imageID与AlbumID相关联,但是到目前为止,我未能做到这一点。 What should I put on my third table that relates the imageID to albumID, and will allow users to put one photo in multiple albums. 我应该在第三张桌子上放些什么,该图片将imageID与albumID相关联,并允许用户将一张照片放入多个相册中。

Also, how will I query it in my php code to the mysql database to display all photos from a particular album? 另外,如何在我的php代码中查询它到mysql数据库以显示特定相册中的所有照片? (i am using mysqli functions) Any help will be very much appreciated! (我正在使用mysqli函数)任何帮助将不胜感激! thanks in advance 提前致谢

Code so far: 到目前为止的代码:

<form enctype="multipart/form-data" method="post">
        <?php
        require_once 'config.php'; 
    $mysqli = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
    if(isset($_POST['upload'])){
        $caption = $_POST['caption'];
        $albumID = $_POST['album'];
        $file = $_FILES ['file']['name'];
        $file_type = $_FILES ['file']['type'];
        $file_size = $_FILES ['file']['size'];
        $file_tmp = $_FILES ['file']['tmp_name'];
        $random_name = rand();

        if(empty($file)){
            echo "Please enter a file <br>";
        } else{
             move_uploaded_file($file_tmp, 'uploads/'.$random_name.'.jpg');
    $ret = mysqli_prepare($mysqli, "INSERT INTO photos (caption, image_url, date_taken, imageID)
    VALUES(?, ?, NOW()), null");
    $filename = "uploads/" . $random_name . ".jpg";
    mysqli_stmt_bind_param($ret, "ss", $caption, $filename);
    mysqli_stmt_execute($ret);
    echo "Photo successfully uploaded!<br>";
    $id = mysqli_prepare($mysqli, "INSERT into album_photo (albumID, imageID) values (?, $id)");
    }
    }
    ?>
    Caption: <br>
    <input type="text" name="caption">
    <br><br>
    Select Album: <br>
    <select name="album">
    <?php
    $mysqli = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
    $result = $mysqli->query("SELECT * FROM albums");
    while ($row = $result->fetch_assoc()) {
        $albumID = $row['albumID'];
        $title = $row['title'];
        echo "<option value='$albumID'>$title</option>";
    }
    ?>
    </select>
    <br><br>
    Select Photo: <br>
    <input type="file" name="file">
    <br><br>
    <input type="submit" name="upload" value="Upload">
</form>

$id = $mysqli->insert_idIf you want to have a photos exist in many albums and albums to have any photos, you would need to create a many-to-many structure. $ id = $ mysqli-> insert_id如果要使照片存在于许多相册中,并且相册中包含任何照片,则需要创建多对多结构。 Typically you would need to create a link table, with dual primary keys. 通常,您需要使用两个主键创建一个链接表。

Basically you just need a table called something like album_photo with two keys. 基本上,您只需要一个带有两个键的名为album_photo类的表。 Both are primary keys in that album, which link to photo and album as foreign keys. 两者都是该相册中的主键,它们作为外键链接到照片和相册。 It could look something like this: 它可能看起来像这样:

albumID (PK)    imageID (PK)
-------         -------
 1                1
 1                2
 2                1
 2                2

By assigning these are both primary keys, this would behave a little different than singular primary keys. 通过将它们都分配为主键,这将与单个主键有所不同。 Rather than having a single id appear only once, they are treated as a primary pair . 而不是具有单一ID只出现一次,它们被视为一个主要的 which means that a grouping can only appear once. 这意味着一个分组只能出现一次。 Also this would make sure that a combo could exist only once. 同样,这将确保一个组合只能存在一次。

You would query it using SQL same as any other query like so (if you want to see a specific album): 您可以像使用任何其他查询一样使用SQL查询它(如果您想查看特定的专辑):

$query = "select a.albumID, p.imageID
          from album a, photos p, album_image ai
          where a.album_ID = ai.albumID
          and p.imageID = ai.imageID
          and a.album_id = ? ";

and then include your variables in your statement to replace the ? 然后在语句中包含您的变量以替换?

For your insert, assuming the user is working from an existing album, the code could look something like this: 对于您的插入内容,假设用户正在使用现有相册,则代码可能类似于以下内容:

 $insert_photo= "insert into photos (caption, image_url, date_taken, imageID)
                 values (?, ?, ?, NULL)";

 $id = [connection variable]->insert_id

$insert_link = "insert into album_photo
                albumID, imageID values (?, ?)
                WHERE albumID = $albumID and imageID = $id";

where the the last ? 最后在哪里? is your current album. 是您当前的相册。 Note, I only included $id in there for ease of explanation, you should also probably prepare that as well, but I won't get into that here. 注意,为了便于说明,我仅在其中包含$ id,您也可能也应该准备它,但在这里我不做介绍。

EDIT: Here's an example from your code (this should get you a little closer, but you are missing a few pieces, and make sure you get the albumID from the one the user chose first, and assuming you are getting this variable through a mysqli_fetch or mysqli_fetch_array into a $row ): 编辑:这是您代码中的一个示例(这应该使您更接近一点,但是您遗漏了几部分,并确保您从用户首先选择的那个中获取了专辑ID,并假设您正在通过mysqli_fetch获取此变量或将mysqli_fetch_array放入$row ):

$albumID = $row['albumID'];
$ret = mysqli_prepare($mysqli, "INSERT INTO photos (caption, image_url, date_taken, imageID)
VALUES(?, ?, NOW(), null");
$filename = "uploads/" . $random_name . ".jpg";
$ret->bind_param("ss", $caption, $filename);
$ret->execute();

$id = $mysqli->insert_id;
$alph = $mysqli->prepare("INSERT into album_photo (albumID, imageID) values (?, ?)  ");

//here you will need to do the rest of the binding parameters, execution, etc, just as in the first query, but off of $alph instead of $ref
$alph->bind_param("ii", $albumID, $id);
$alph->execute();
$alph->close();
$ret->close();
echo "Photo successfully uploaded!<br>";

Have you tried using an ORM like Doctrine or Eloquent? 您是否尝试过使用Doctrine或Eloquent之类的ORM? You can use those to implement a many-to-many relationship (which is the technical name for what you're trying to do here). 您可以使用它们来实现many-to-many关系(这是您要在此处执行的操作的技术名称)。

This answer is a good summary for how to implement a simple many-to-many relationship in SQL. 对于如何在SQL中实现简单的多对多关系, 此答案是一个很好的总结。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM