我正在尝试学习和理解PHP和MySQL。我决定做一个小项目,并随着我的进步而学习。
现在我的数据库是这样的(我试图在没有所有字段的情况下保持它的整洁):
users
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) NOT NULL,
articles
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
body TEXT NOT NULL
要显示我使用PHP PDO的所有文章
$sql = 'SELECT * FROM articles';
$query = $db->prepare($query);
$query->execute();
$articles = $query->fetchAll();
为了显示单个文章,我创建了新的article.php页面,并与此
$id = $_GET['id'];
$sql = 'SELECT * FROM articles WHERE id = :id';
$query = $db->prepare($sql);
$query->execute(['id' => $id]);
$article = $query->fetch();
id是来自索引页面的
<a href="<?php echo ROOT_URL ?>article.php?id=<?php echo $article['id'];?>Read Post</a>
到目前为止,一切正常,但是我的第一个问题是如何为所有帖子分类。我想到要通过添加FOREIGN KEY来创建新表并更改Articles表:
articles
FOREGEIN KEY (cat_id) REFERENCES categories(id)
ON DELETE CASCADE ON UPDATE CASCADE
categories
id INT NOT NULL AUTO INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL
但是现在我不知道该如何查询以获取与article.php相似类别的所有文章,而应该是category.php。
我的第二个问题是我应该使用哪种查询来使用户对文章发表评论。我知道桌子的外观如何
comments
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
body varchar(255) NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id)
ON DELETE CASCADE ON UPDATE CASCADE
FOREIGN KEY (post_id) REFERENCES posts(id)
ON DELETE CASCADE ON UPDATE CASCADE
我写了这样的东西
if (isset($_POST['comment'])) {
$body = $_POST['body'];
$article_id = $_POST['article_id'];
$user_id = $_SESSION['id'];
$sql = "INSERT INTO comments(user_id, article_id, body) VALUES (:user_id, :article_id, :body)";
$query = $db->prepare($sql);
$query->execute(['user_id' => $user_id, 'article_id' => $article_id, 'body' => $body]);
}
<input type="hidden" name="article_id" value="<?php echo $article['id'] ?>">
<button type="submit" name="comment">Leave a Comment</button>
但是所有文章都发表了评论。
答案 0 :(得分:0)
如果要选择所有文章,则其中一个属于某个类别。您可以执行以下操作。
$id = $_GET['category_id'];
$sql = 'SELECT * FROM articles WHERE cat_id = :id';
$query = $db->prepare($sql);
$query->execute(['id' => $id]);
foreach($query->fetchAll() as $results){
// Here you can make a magic.
echo '<h2>' . $results['Article_Name'] . '</h2>';
print_r($results);
}
您可以对注释执行相同的原则。只是在每个文章页面上进行查询。
例如,像这个。
SELECT * FROM comments WHERE article_id = :article_id
答案 1 :(得分:0)
如何进行查询以将所有具有相同类别的文章都替换为article.php,而将其改为category.php
字面上是一样的,只是名称改变了:
SELECT *
FROM articles
WHERE cat_id = :cat_id
但是,我认为您迟早需要连接表,这是关系数据库的核心功能(不幸的是,许多开发人员认为SELECT * FROM tablename
是您将要使用的所有SQL。需要)。在这种情况下,您可以执行以下操作:
SELECT cat.id AS cat_id, cat.name AS cat_name, art.id AS art_id, art.body
FROM categories cat
INNER JOIN articles art ON cat.id = art.cat_id
WHERE cat.id = :cat_id
ORDER BY art.id DESC
有一篇经典文章很好地解释了这一点:A Visual Explanation of SQL Joins
我应该使用哪种查询使用户能够对文章发表评论
您不会真正陷入困境,但基本上是同一故事(相同的查询,不同的名称):
SELECT *
FROM comments
WHERE post_id = :post_id
最后,有两个随机提示:
我不会为ON DELETE CASCADE
设置articles.cat_id
。我看不到按类别批量删除文章的现实生活用法,并且很容易出错。
尝试使命名保持一致。您只有4个实体,并且您已经在同一内容(类别与类别,文章与帖子)中使用了不同的术语。
答案 2 :(得分:-2)
Mysql表示例:
CREATE TABLE IF NOT EXISTS `articles` (
`id` bigint(22) NOT NULL AUTO_INCREMENT,
`userid` bigint(22) NOT NULL DEFAULT 0,
`catid` bigint(22) NOT NULL DEFAULT 0,
`title` varchar(190) NOT NULL DEFAULT '',
`text` text,
`active` int(1) NOT NULL DEFAULT 1,
`ban` int(3) NOT NULL DEFAULT 0,
`ip` varchar(200) NOT NULL DEFAULT '',
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `ukey` (`userid`,`title`),
KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS `categories` (
`id` bigint(22) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`slug` varchar(50) NOT NULL,
`active` int(1) NOT NULL DEFAULT 1,
PRIMARY KEY (`id`),
UNIQUE KEY `ukey` (`slug`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
// Add first category (after this id = 1 for example)
INSERT INTO categories(name,slug) VALUES('Category 1', 'cat1-slug')
// Here userid == logged user id
// Here: catid == id field from categories table (category id from categories table)
INSERT INTO articles(userid,catid,title,text) VALUES(1,1,'Article title','Article content')
选择具有类别名称的文章(mysql连接)
SELECT articles.*,categories.name,categories.slug,categories.id as catid from articles LEFT JOIN categories ON articles.catid = categories.id WHERE articles.active = 1 AND articles.catid = 1
不使用它,不需要它:
FOREGEIN KEY (cat_id) REFERENCES categories(id)
ON DELETE CASCADE ON UPDATE CASCADE