PHP标记系统-会话故障
我正试图为我的漫画网站实现一个标签系统 其目标与SO类似-用户可以单击多个标记,这些标记将保留在一起-主要区别在于我使用$u会话来存储它们,而不是这样的登录系统 一旦用户点击一个标签,它会将显示的漫画限制为与标签id匹配的漫画。有人建议我有3个单独的表——一个用于漫画,一个用于标签,以及一个关系表ComicTags。一个漫画可以有0个或多个标记,一个标记可以与1个或多个漫画相关联 我正在努力编写正确的sql查询,以将漫画id与0个或多个标记id连接起来 我的桌子会这样摆吗PHP标记系统-会话故障,php,mysql,Php,Mysql,我正试图为我的漫画网站实现一个标签系统 其目标与SO类似-用户可以单击多个标记,这些标记将保留在一起-主要区别在于我使用$u会话来存储它们,而不是这样的登录系统 一旦用户点击一个标签,它会将显示的漫画限制为与标签id匹配的漫画。有人建议我有3个单独的表——一个用于漫画,一个用于标签,以及一个关系表ComicTags。一个漫画可以有0个或多个标记,一个标记可以与1个或多个漫画相关联 我正在努力编写正确的sql查询,以将漫画id与0个或多个标记id连接起来 我的桌子会这样摆吗 $result = $
$result = $mysqli->query("SELECT * FROM comics c INNER JOIN comictags ct ON (c.id = ct.comicID) WHERE ct.tagID IN (1, 2, 3) GROUP BY c.id");
我的查询是这样的吗
$result = $mysqli->query("SELECT * FROM comics c INNER JOIN comictags ct ON (c.id = ct.comicID) WHERE ct.tagID IN (1, 2, 3) GROUP BY c.id");
谢谢
编辑 我的想象正确吗 1) 首先从漫画和标签中选择所有列 2) 将喜剧id加入ComicTags表中的匹配id 3) 将标记id加入ComicTags表中的匹配id 4) 在这种情况下,仅选择标记id为1或2的标记。。。这样就可以返回所有的喜剧ID
编辑2:代码
<?php
session_start();
include 'dbconnect.php';
$site = (isset($_GET['site']) ? ($_GET['site']) : "comics");
$tag = $_GET['_tagChoice'];
if (!isset($_SESSION['tags'])) {
$_SESSION['tags'] = array();
}
$tag = $mysqli->real_escape_string($tag);
$_SESSION['tags'][] = $tag;
foreach ($_SESSION['tags'] as $tag) {
echo $tag;
}
$_SESSION['tags'] = array_unique($_SESSION['tags']);
$result = $mysqli->query(
"SELECT c.*, t.*
FROM comics c
LEFT JOIN comictags ct ON (c.id = ct.comicID)
LEFT JOIN tags t ON (t.id = ct.tagID)
WHERE ct.tagname IN (" . implode(',', $_SESSION['tags']). ")
OR ct.tagname IS NULL");
mysqli_close($mysqli);
while ($row = $result->fetch_assoc()) {
echo $row['comic_id'];
}
//session_destroy();
?>
您需要通过comicstags
表连接到标记
表,以获得标记名
。因此,再添加一个内部联接
:
SELECT
/* Selecting all columns from comics and tags, not from comicstags */
c.*,
t.*
FROM
comics c
/* First join matches comics to comicstags */
INNER JOIN comictags ct ON (c.id = ct.comicID)
/* Second join pairs comicstags to tags */
INNER JOIN tags t ON (t.TagID = ct.TagID)
WHERE
ct.tagID IN (1, 2, 3)
/* Or those which have no tags */
OR ct.tagID IS NULL
由于未使用聚合(COUNT()、SUM()、MIN()、MAX()
等),因此删除了分组依据。如果只需要唯一的行,请将DISTINCT
添加到SELECT
中,使用以下方法:
select t.TagId,t.TagNamem,cs.Path from Tag t
inner join ComicTag ct
on(t.TagId =ct.TagId)
inner join Comics cs
on(ct.ComicID = cs.Comic_id)
where t.TagId = $tag_cliked
我希望这有帮助
萨卢多斯;) 您在分组时没有使用聚合函数,因此除了db找到的第一个标记外,您将丢失所有标记。我认为您应该考虑使用持久cookie而不是会话来存储此用户标记选择数据。这样,当用户在几天/几周/几个月后在同一个浏览器上返回时,他们的标签仍然可用。会话在短时间的不活动后被(并且应该)清理干净。@leftclickben好的,我不知道如何实现它。您知道有什么好的资源吗?@Growler使用cookie与在$\u会话中使用cookie非常相似。您必须调用setcookie('tags','1,2,3',time()+86400*600)
(例如,在600天内使其过期),而不是写入$\u COOKIE
。但是可以从$\u COOKIE['tags']
读取该值,就像从$\u会话
读取该值一样。在将其传递到查询之前,请确保对其进行消毒。谢谢,Michael!我在上面做了一个编辑,把逻辑画出来,这样我就可以把它形象化了——介意确认我的理解吗?@Growler是的,你的图表准确地映射了这些关系。好的,谢谢。我现在就接受答案,但我要到下班后才能实施。我可能还有一些问题问,对于(1,2,3)
中的ct.tagID,我如何动态指定只查询用户选择的标记?似乎我在为1、2或3硬编码ct.tagID。@Growler不,您需要“…在(“.intlode(',',$”会话['tags'))。”)“…
我不能强调这一点,您必须首先验证$”会话['tags']
中的所有内容都是整数。