如何用PHP和MySQL开发自己的讨论区系统的方法

174 阅读2分钟

在本教程中,我们将解释如何用PHP和MySQL开发自己的讨论区系统。我们在本教程中创建了一个运行中的论坛实例,可以下载完整的实例代码,以增强其创建自己的论坛。

论坛系统是为人们提供的地方,他们可以在那里开始讨论主题。论坛由管理员或版主控制,他们创建论坛类别并管理论坛的权限。

注册会员可以创建自己的讨论主题,也可以参与现有的讨论。访客会员也可以创建和参与讨论。

所以,让我们开始用PHP和MySQL开发论坛系统。主要的文件有:

  • category.php:用于列出类别和类别主题的文件。
  • Category.php:一个保存与类别有关的方法的类。
  • Topics.php:一个包含与主题相关的方法的类。
  • posts.php:用快速回复编辑器列出主题帖子的文件。
  • Post.php:一个包含与帖子相关的方法的类。

步骤1:创建MySQL数据库表

由于论坛中有分类、主题、帖子,所以首先我们将创建MySQL数据库表forum_category 来存储分类。

CREATE TABLE `forum_category` (
  `category_id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `description` text NOT NULL,
  `is_category` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

ALTER TABLE `forum_category`
  ADD PRIMARY KEY (`category_id`);
  
ALTER TABLE `forum_category`
  MODIFY `category_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=6;

我们将创建表forum_topics 来存储类别主题。

CREATE TABLE `forum_topics` (
  `topic_id` int(11) NOT NULL,
  `subject` varchar(255) NOT NULL,
  `category_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `created` datetime NOT NULL DEFAULT current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

ALTER TABLE `forum_topics`
  ADD PRIMARY KEY (`topic_id`);
  
ALTER TABLE `forum_topics`
  MODIFY `topic_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;

我们将创建表forum_posts 来存储主题帖子。

CREATE TABLE `forum_posts` (
  `post_id` int(11) NOT NULL,
  `message` text NOT NULL,
  `topic_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `created` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

ALTER TABLE `forum_posts`
  ADD PRIMARY KEY (`post_id`);
  
ALTER TABLE `forum_posts`
  MODIFY `post_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;

我们将创建表forum_users 来存储用户。

CREATE TABLE `forum_users` (
  `user_id` int(11) NOT NULL,
  `username` varchar(255) NOT NULL,
  `password` varchar(50) NOT NULL,
  `name` varchar(255) NOT NULL,
  `email` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

ALTER TABLE `forum_users`
  ADD PRIMARY KEY (`user_id`);
  
ALTER TABLE `forum_users`
  MODIFY `user_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;  

第二步:分类列表

我们将实现设计和功能来列出论坛的类别。为此,我们将对category.php 文件进行修改。我们将从类Category.php 中调用方法getCategoryList() ,以获得类别列表。

<div class="single category">			
	<ul class="list-unstyled">
		<li><span style="font-size:25px;font-weight:bold;">Categories</span> <span class="pull-right"><span style="font-size:20px;font-weight:bold;">Topics / Posts</span></span></li>
		<?php
		$result = $categories->getCategoryList();
		while ($category = $result->fetch_assoc()) {
			$categories->category_id = $category['category_id'];
			$totalTopic = $categories->getCategoryTopicsCount();
			$totalPosts = $categories->getCategoryPostsCount();
		?>
		<li><a href="category.php?category_id=<?php echo $category['category_id'];?>" title=""><?php echo $category['name']; ?> <span class="pull-right"><?php echo $totalTopic; ?> / <?php echo $totalPosts; ?></span></a></li>			
		<?php } ?>
	</ul>
</div>

我们将在类Category.php 中实现方法getCategoryList() ,从MySQL数据库表forum_category 中获取类别并返回。

public function getCategoryList(){		
	$sqlQuery = "
		SELECT *
		FROM ".$this->categoryTable." ORDER BY category_id DESC";
	
	$stmt = $this->conn->prepare($sqlQuery);
	$stmt->execute();
	$result = $stmt->get_result();			
	return $result;	
}

第三步:主题列表

我们将对设计进行修改,并实现列出访问过的类别主题的功能。为此,我们将对category.php 文件进行修改,并从类Topic.php 中调用方法getTopicList() 来列出类别主题。

<div class="single category">
	<?php 
	$categories->category_id = $_GET['category_id'];
	$categoryDetails = $categories->getCategory();
	?>
	<span style="font-size:20px;"><a href="category.php"><< <?php echo $categoryDetails['name']; ?></a></span>
	<br>	<br>		
	<ul class="list-unstyled">
		<li><span style="font-size:20px;font-weight:bold;">Topics</span> <span class="pull-right"><span style="font-size:15px;font-weight:bold;">Posts</span></span></li>
		<?php
		$topics->category_id = $_GET['category_id'];
		$result = $topics->getTopicList();
		while ($topic = $result->fetch_assoc()) {
			$topics->topic_id = $topic['topic_id'];
			$totalTopicPosts = $topics->getTopicPostCount();
		?>
		<li><a href="post.php?topic_id=<?php echo $topic['topic_id'];?>" title=""><?php echo $topic['subject']; ?> <span class="pull-right"><?php echo $totalTopicPosts; ?></span></a></li>			
		<?php } ?>
	</ul>
</div>	

我们将从类Topic.php 中实现方法getTopicList() ,从表category_topics 中获取类别主题列表,以列出主题。

public function getTopicList(){	
	if($this->category_id) {
		$sqlQuery = "
			SELECT c.name, c.category_id, t.subject, t.topic_id, t.user_id, t.created 			
			FROM ".$this->topicTable." as t 
			LEFT JOIN ".$this->categoryTable." as c ON t.category_id = c.category_id
			WHERE t.category_id = ".$this->category_id."
			ORDER BY t.topic_id DESC";			
		$stmt = $this->conn->prepare($sqlQuery);
		$stmt->execute();
		$result = $stmt->get_result();			
		return $result;	
	}
}

第四步:帖子列表

我们将在文件post.php 中实现列出主题的帖子回复的功能。为此,我们将从类Topic.php 中调用方法getPosts() ,以列出主题帖子。

<div class="posts list">
	<?php 
	$topics->topic_id = $_GET['topic_id'];
	$topicDetails = $topics->getTopic();
	?>
	<span style="font-size:20px;"><a href="category.php?category_id=<?php echo $topicDetails['category_id']; ?>"><< <?php echo $topicDetails['subject']; ?></a></span>
	<br><br>
	<?php				
	$result = $topics->getPosts();
	while ($post = $result->fetch_assoc()) {
		$date = date_create($post['created']);
		$posterName = $post['username'];
		if($posterName == '') {
			$posterName = $post['name'];
		}
	?>
	<article class="row" id="postRow_<?php echo $post['post_id']; ?>">
		<div class="col-md-2 col-sm-2 hidden-xs">
		  <figure class="thumbnail">
			<img class="img-responsive" src="images/user-avatar.png" />
			<figcaption class="text-center"><?php echo ucwords($posterName); ?></figcaption>
		  </figure>
		</div>
		<div class="col-md-10 col-sm-10">
		  <div class="panel panel-default arrow left">
			<div class="panel-body">
			  <header class="text-left">
				<div class="comment-user"><i class="fa fa-user"></i> By: <?php echo $posterName; ?></div>
				<time class="comment-date" datetime="16-12-2014 01:05"><i class="fa fa-clock-o"></i> <?php echo date_format($date, 'd M Y H:i:s'); ?></time>
			  </header>
			  <br>					  
			  <div class="comment-post"  id="post_message_<?php echo $post['post_id']; ?>">
				
				<?php echo $post['message']; ?>
				
			  </div>
			  
			  <textarea name="message" data-topic-id="<?php echo $post['topic_id']; ?>" id="<?php echo $post['post_id']; ?>" style="visibility: hidden;"></textarea><br>
			  
			  <div class="text-right" id="button_section_<?php echo $post['post_id']; ?>">
				<a class="btn btn-default btn-sm" id="edit_<?php echo $post['post_id']; ?>"><i class="fa fa-reply"></i> Edit</a>
				<a class="btn btn-default btn-sm"><i class="fa fa-reply"></i> Delete</a>
			  </div>			
				
			<div id="editSection_<?php echo $post['post_id']; ?>" class="hidden">						
				<button type="submit" id="save_<?php echo $post['post_id']; ?>" name="save" class="btn btn-info saveButton">Save</button>
				<button type="submit" id="cancel_<?php echo $post['post_id']; ?>" name="cancel" class="btn btn-info saveButton">Cancel</button>
			</div>					
			</div>					
	
		  </div>
		</div>
	</article>	
	<?php } ?>				
</div>

我们将在类Topic.php 中实现方法getPosts() ,从表category_posts 中获取主题帖子,以列出它们。

public function getPosts(){	
	if($this->topic_id) {
		$sqlQuery = "
			SELECT t.topic_id, p.post_id, p.message, p.topic_id, p.user_id, p.created, u.username			
			FROM ".$this->topicTable." as t 
			LEFT JOIN ".$this->postTable." as p ON t.topic_id = p.post_id
			LEFT JOIN ".$this->userTable." as u ON p.user_id = u.user_id
			WHERE p.topic_id = ".$this->topic_id."
			ORDER BY p.post_id ASC";			
		$stmt = $this->conn->prepare($sqlQuery);
		$stmt->execute();
		$result = $stmt->get_result();			
		return $result;	
	}
}