如何为所有帖子分类?

时间:2019-08-31 15:29:38

标签: php mysql foreign-keys

我正在尝试学习和理解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>

但是所有文章都发表了评论。

3 个答案:

答案 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