我有两个来自mysql数据库的表,具有以下模式:
相册:标题、创建日期、修改日期、相册ID(主键)照片:标题,image_url,date_taken,imageID(主键)
我正在创建一个php/mysql支持的在线相册,我想允许一张照片出现在多个相册中,所以我没有把albumID作为外键放在照片中。我能做到这一点的唯一方法是创建第三个表,将imageID与albumID关联起来,但到目前为止我还没能做到。我应该在第三张表上放些什么,它将imageID与albumID联系起来,并允许用户将一张照片放在多个相册中。
此外,我将如何在php代码中将其查询到mysql数据库,以显示特定相册中的所有照片?(我使用的是mysqli函数)任何帮助都将不胜感激!提前感谢
到目前为止的代码:
<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>
您是否尝试过使用类似ORM的Doctrine或Eloquent?您可以使用它们来实现many-to-many
关系(这是您在这里尝试做的事情的技术名称)。
这个答案很好地总结了如何在SQL中实现简单的多对多关系。
$id=$mysqli->insert_id如果你想让一张照片存在于多个相册和相册中以拥有任何照片,你需要创建一个多对多的结构。通常,您需要创建一个具有双主键的链接表。
基本上,您只需要一个名为album_photo
的带有两个键的表。两者都是该相册中的主键,作为外键链接到照片和相册。它可能看起来像这样:
albumID (PK) imageID (PK)
------- -------
1 1
1 2
2 1
2 2
通过指定这两个都是主键,这将与奇异主键的行为略有不同。与其让单个id只出现一次,不如将其视为主对。这意味着分组只能出现一次。这也将确保一个组合只能存在一次。
您可以使用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 = ? ";
然后在您的语句中包含您的变量以替换?
对于插入,假设用户使用的是现有相册,代码可能如下所示:
$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";
最后一个在哪里?是您当前的相册。注意,为了便于解释,我只在其中包含了$id,你可能也应该准备好,但我不会在这里讨论。
编辑:以下是您代码中的一个示例(这应该会让您更接近,但您遗漏了一些部分,并确保您从用户首先选择的那个中获取白蛋白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>";