PHP Projects With Source Code

Blogging Platform Project In Php


Creating a Blogging Platform involves several components, including a MySQL database schema, file structure, layout design using Bootstrap 5, and complete PHP scripts for user authentication and management. Below is a comprehensive guide to help you set up your system.

Project Introduction

The Blogging Platform is a web application designed to facilitate the creation, management, and sharing of blog content. It provides a user-friendly interface for authors, editors, and administrators to publish posts, manage comments, categorize content, and interact with readers. The platform supports user authentication, allowing different roles with varying permissions, ensuring a secure and organized environment for content creation and management.

Project Objectives

  • To develop a robust database schema that supports user management, post creation, and content categorization.
  • To implement a secure authentication system for users with different roles (admin, author, editor, reader).
  • To create a responsive and intuitive user interface for seamless navigation and content interaction.
  • To enable users to create, edit, and delete posts, comments, and media efficiently.
  • To provide a notification system for user interactions and updates.
  • To ensure the platform is scalable and maintainable for future enhancements.

Project Modules

  1. User Management: Handles user registration, login, role assignment, and profile management.
  2. Post Management: Allows users to create, edit, delete, and view blog posts with options for drafts and published statuses.
  3. Comment System: Enables readers to leave comments on posts, with moderation features for approval and deletion.
  4. Category and Tag Management: Facilitates the organization of posts through categories and tags for better content discovery.
  5. Media Management: Provides functionality for users to upload and manage media files associated with posts.
  6. Notification System: Sends alerts to users regarding comments, post updates, and other relevant activities.
  7. Admin Dashboard: A dedicated interface for administrators to manage users, posts, comments, and overall platform settings.

1. MySQL Database Schema


CREATE DATABASE blogging_platform;
USE blogging_platform;
-- Table for users
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    password VARCHAR(255) NOT NULL,
    email VARCHAR(100) NOT NULL UNIQUE,
    role ENUM('admin', 'author', 'editor', 'reader') DEFAULT 'reader',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Table for posts
CREATE TABLE posts (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id `INT` NOT NULL,
    title VARCHAR(255) NOT NULL,
    content VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    status ENUM('draft', 'published') DEFAULT 'draft',
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
-- Table for comments
CREATE TABLE comments (
    id INT AUTO_INCREMENT PRIMARY KEY,
    post_id `INT` NOT NULL,
    user_id `INT` NOT NULL,
    content VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    status ENUM('pending', 'approved', 'deleted') DEFAULT 'pending',
    FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE,
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
-- Table for categories
CREATE TABLE categories (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL UNIQUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Table for post categories
CREATE TABLE post_categories (
    post_id `INT` NOT NULL,
    category_id `INT` NOT NULL,
    PRIMARY KEY (post_id, category_id),
    FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE,
    FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE CASCADE
);
-- Table for tags
CREATE TABLE tags (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL UNIQUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Table for post tags
CREATE TABLE post_tags (
    post_id `INT` NOT NULL,
    tag_id `INT` NOT NULL,
    PRIMARY KEY (post_id, tag_id),
    FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE,
    FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE
);
-- Table for media
CREATE TABLE media (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id `INT` NOT NULL,
    file_path VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
-- Table for notifications
CREATE TABLE notifications (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id `INT` NOT NULL,
    message VARCHAR(255) NOT NULL,
    is_read TINYINT(1) DEFAULT FALSE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

2. File and Folder Structure


blogging_platform/
│
├── config/
│   └── db.php
│
├── public/
│   ├── index.php
│   ├── login.php
│   ├── register.php
│   ├── dashboard.php
│   ├── create_post.php
│   ├── edit_post.php
│   ├── view_post.php
│   ├── comments.php
│   ├── categories.php
│   ├── tags.php
│   ├── media.php
│   ├── notifications.php
│   └── admin_dashboard.php
│
├── includes/
│   ├── header.php
│   ├── footer.php
│   └── functions.php
│
├── assets/
│   ├── css/
│   │   └── styles.css
│   ├── js/
│   │   └── scripts.js
│   └── images/
│
└── vendor/
    └── (Bootstrap and other libraries)

3. Layout Based Design with Bootstrap 5

Header (includes/header.php)


<!DOCTYPE html>
<html lang=`en`>
<head>
    <meta charset=`UTF-8`>
    <meta name=`viewport` content=`width=device-width, initial-scale=1.0`>
    <link href=`https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css` rel=`stylesheet`>
    <link rel=`stylesheet` href=`assets/css/styles.css`>
    <title>Blogging Platform</title>
</head>
<body>
 <div class=`container`>
        <header class=`my-4`>
            <h1>Blogging Platform</h1>
        </header>
        <nav class=`navbar navbar-expand-lg navbar-light bg-light`>
            <div class=`container-fluid`>
                <a class=`navbar-brand` href=`index.php`>Home</a>
                <button class=`navbar-toggler` type=`button` data-bs-toggle=`collapse` data-bs-target=`#navbarNav` aria-controls=`navbarNav` aria-expanded=`false` aria-label=`Toggle navigation`>
                    <span class=`navbar-toggler-icon`></span>
                </button>
                <div class=`collapse navbar-collapse` id=`navbarNav`>
                    <ul class=`navbar-nav`>
                        <li class=`nav-item`>
                            <a class=`nav-link` href=`create_post.php`>Create Post</a>
                        </li>
                        <li class=`nav-item`>
                            <a class=`nav-link` href=`categories.php`>Categories</a>
                        </li>
                        <li class=`nav-item`>
                            <a class=`nav-link` href=`tags.php`>Tags</a>
                        </li>
                        <li class=`nav-item`>
                            <a class=`nav-link` href=`media.php`>Media</a>
                        </li>
                        <li class=`nav-item`>
                            <a class=`nav-link` href=`notifications.php`>Notifications</a>
                        </li>
                        <li class=`nav-item`>
                            <a class=`nav-link` href=`login.php`>Login</a>
                        </li>
                        <li class=`nav-item`>
                            <a class=`nav-link` href=`register.php`>Register</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
        <main class=`my-4`>

Footer (includes/footer.php)


        </main>
        <footer class=`text-center my-4`>
            <p>© 2023 Blogging Platform. All rights reserved.</p>
        </footer>
    </div>
    <script src=`https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js`></script>
</body>
</html>

4. PHP Code for User Authentication

Registration (public/register.php)


<?php
require '../config/db.php';
require '../includes/header.php';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $username = $_POST['username'];
    $email = $_POST['email'];
    $password = password_hash($_POST['password'], PASSWORD_DEFAULT);
    $role = $_POST['role'];
    $stmt = $conn->prepare(`INSERT INTO users (username, email, password, role) VALUES (?, ?, ?, ?)`);
    $stmt->bind_param(`ssss`, $username, $email, $password, $role);
    $stmt->execute();
    $stmt->close();
    header(`Location: login.php`);
}
?>
<form method=`POST` action=``>
    <div class=`mb-3`>
        <label for=`username` class=`form-label`>Username</label>
        <input type=`text` class=`form-control` id=`username` name=`username` required>
    </div>
    <div class=`mb-3`>
        <label for=`email` class=`form-label`>Email</label>
        <input type=`email` class=`form-control` id=`email` name=`email` required>
    </div>
    <div class=`mb-3`>
        <label for=`password` class=`form-label`>Password</label>
        <input type=`password` class=`form-control` id=`password` name=`password` required>
    </div>
    <div class=`mb-3`>
        <label for=`role` class=`form-label`>Role</label>
        <select class=`form-select` id=`role` name=`role`>
            <option value=`reader`>Reader</option>
            <option value=`author`>Author</option>
            <option value=`editor`>Editor</option>
            <option value=`admin`>Admin</option>
        </select>
    </div>
    <button type=`submit` class=`btn btn-primary`>Register</button>
</form>
<?php require '../includes/footer.php'; ?>

Login (public/login.php)


<?php
session_start();
require '../config/db.php';
require '../includes/header.php';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $username = $_POST['username'];
    $password = $_POST['password'];
    $stmt = $conn->prepare(`SELECT * FROM users WHERE username = ?`);
    $stmt->bind_param(`s`, $username);
    $stmt->execute();
    $result = $stmt->get_result();
    $user = $result->fetch _assoc();
    if ($user && password_verify($password, $user['password'])) {
        $_SESSION['user_id'] = $user['id'];
        $_SESSION['role'] = $user['role'];
        header(`Location: dashboard.php`);
    } else {
        echo `Invalid credentials.`;
    }
}
?>
<form method=`POST` action=``>
    <div class=`mb-3`>
        <label for=`username` class=`form-label`>Username</label>
        <input type=`text` class=`form-control` id=`username` name=`username` required>
    </div>
    <div class=`mb-3`>
        <label for=`password` class=`form-label`>Password</label>
        <input type=`password` class=`form-control` id=`password` name=`password` required>
    </div>
    <button type=`submit` class=`btn btn-primary`>Login</button>
</form>
<?php require '../includes/footer.php'; ?>

5. Additional PHP Scripts

Dashboard (public/dashboard.php)


<?php
session_start();
require '../config/db.php';
require '../includes/header.php';
if (!isset($_SESSION['user_id'])) {
    header(`Location: login.php`);
    exit();
}
$user_id = $_SESSION['user_id'];
$stmt = $conn->prepare(`SELECT * FROM users WHERE id = ?`);
$stmt->bind_param(`i`, $user_id);
$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_assoc();
?>
<h2>Welcome, <?php echo $user['username']; ?></h2>
<p>Your role: <?php echo ucfirst($user['role']); ?></p>
<?php require '../includes/footer.php'; ?>

Create Post (public/create_post.php)


<?php
session_start();
require '../config/db.php';
require '../includes/header.php';
if (!isset($_SESSION['user_id'])) {
    header(`Location: login.php`);
    exit();
}
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $user_id = $_SESSION['user_id'];
    $title = $_POST['title'];
    $content = $_POST['content'];
    $status = $_POST['status'];
    $stmt = $conn->prepare(`INSERT INTO posts (user_id, title, content, status) VALUES (?, ?, ?, ?)`);
    $stmt->bind_param(`isss`, $user_id, $title, $content, $status);
    $stmt->execute();
    $stmt->close();
    header(`Location: dashboard.php`);
}
?>
<form method=`POST` action=``>
    <div class=`mb-3`>
        <label for=`title` class=`form-label`>Title</label>
        <input type=`text` class=`form-control` id=`title` name=`title` required>
    </div>
    <div class=`mb-3`>
        <label for=`content` class=`form-label`>Content</label>
        <textarea class=`form-control` id=`content` name=`content` rows=`5` required></textarea>
    </div>
    <div class=`mb-3`>
        <label for=`status` class=`form-label`>Status</label>
        <select class=`form-select` id=`status` name=`status`>
            <option value=`draft`>Draft</option>
            <option value=`published`>Published</option>
        </select>
    </div>
    <button type=`submit` class=`btn btn-primary`>Create Post</button>
</form>
<?php require '../includes/footer.php'; ?>

View Post (public/view_post.php)


<?php
session_start();
require '../config/db.php';
require '../includes/header.php';
if (isset($_GET['id'])) {
    $post_id = $_GET['id'];
    $stmt = $conn->prepare(`SELECT posts.*, users.username FROM posts JOIN users ON posts.user_id = users.id WHERE posts.id = ?`);
    $stmt->bind_param(`i`, $post_id);
    $stmt->execute();
    $result = $stmt->get_result();
    $post = $result->fetch_assoc();
}
?>
<h2><?php echo $post['title']; ?></h2>
<p>By <?php echo $post['username']; ?> on <?php echo $post['created_at']; ?></p>
<div><?php echo nl2br($post['content']); ?></div>
<?php require '../includes/footer.php'; ?>

Comments (public/comments.php)


<?php
session_start();
require '../config/db.php';
require '../includes/header.php';
if (isset($_POST['post_id']) && isset($_SESSION['user_id'])) {
    $post_id = $_POST['post_id'];
    $user_id = $_SESSION['user_id'];
    $content = $_POST['content'];
    $stmt = $conn->prepare(`INSERT INTO comments (post_id, user_id, content) VALUES (?, ?, ?)`);
    $stmt->bind_param(`iis`, $post_id, $user_id, $content);
    $stmt->execute();
    $stmt->close();
}
if (isset($_GET['post_id'])) {
    $post_id = $_GET['post_id'];
    $stmt = $conn->prepare(`SELECT comments.*, users.username FROM comments JOIN users ON comments.user_id = users.id WHERE comments.post_id = ? AND comments.status = 'approved'`);
    $stmt->bind_param(`i`, $post_id);
    $stmt->execute();
    $result = $stmt->get_result();
    $comments = $result->fetch_all(MYSQLI_ASSOC);
}
?>
<h3>Comments</h3>
<form method=`POST` action=``>
    <input type=`hidden` name=`post_id` value=`<?php echo $post_id; ?>`>
    <div class=`mb-3`>
        <label for=`content` class=`form-label`>Leave a Comment</label>
        <textarea class=`form-control` id=`content` name=`content` rows=`3` required></textarea>
    </div>
    <button type=`submit` class=`btn btn-primary`>Submit</button>
</form>
<ul class=`list-group mt-3`>
    <?php foreach ($comments as $comment): ?>
    <li class=`list-group-item`>
        <strong><?php echo $comment['username']; ?></strong>: <?php echo $comment['content']; ?>
    </li>
    <?php endforeach; ?>
</ul>
<?php require '../includes/footer.php'; ?>

Categories (public/categories.php)


<?php
require '../config/db.php';
require '../includes/header.php';
$stmt = $conn->prepare(`SELECT * FROM categories`);
$stmt->execute();
$result = $stmt->get_result();
$categories = $result->fetch_all(MYSQLI_ASSOC);
?>
<h3>Categories</h3>
<ul class=`list-group`>
    <?php foreach ($categories as $category): ?>
    <li class=`list-group-item`><?php echo $category['name']; ?></li>
    <?php endforeach; ?>
</ul>
<?php require '../includes/footer.php'; ?>

Tags (public/tags.php)


<?php
require '../config/db.php';
require '../includes/header.php';
$stmt = $conn->prepare(`SELECT * FROM tags`);
$stmt->execute();
$result = $stmt->get_result();
$tags = $result->fetch_all(MYSQLI_ASSOC);
?>
<h3>Tags</h3>
<ul class=`list-group`>
    <?php foreach ($tags as $tag): ?>
    <li class=`list-group-item`><?php echo $tag['name']; ?></li>
    <?php endforeach; ?>
</ul>
<?php require '../includes/footer.php'; ?>

Media (public/media.php)


<?php
session_start();
require '../config/db.php';
require '../includes/header.php';
if (isset($_POST['upload'])) {
    $user_id = $_SESSION['user_id'];
    $file_path = 'uploads/' . basename($_FILES['media']['name']);
    move_uploaded_file($_FILES['media']['tmp_name'], $file_path);
    $stmt = $conn->prepare(`INSERT INTO media (user_id, file_path) VALUES (?, ?)`);
    $stmt->bind_param(`is`, $user_id, $file_path);
    $stmt->execute();
    $stmt->close();
}
$stmt = $conn->prepare(`SELECT * FROM media WHERE user_id = ?`);
$stmt->bind_param(`i`, $_SESSION['user_id']);
$stmt->execute();
$result = $stmt->get_result();
$media_files = $result->fetch_all(MYSQLI_ASSOC);
?>
<h3>Media Library</h3>
<form method=`POST` enctype=`multipart/form-data`>
    <div class=`mb-3`>
        <label for=`media` class=`form-label`>Upload Media</label>
        <input type=`file` class=`form-control` id=`media` name=`media` required>
    </div>
    <button type=`submit` name=`upload` class=`btn btn-primary`>Upload</button>
</form>
<h4>Your Media Files</h4>
<ul class=`list-group mt-3`>
    <?php foreach ($media_files as $file): ?>
    <li class=`list-group-item`>
        <a href=`<?php echo $file['file_path']; ?>` target=`_blank`><?php echo basename($file['file_path']); ?></a>
    </li>
    <?php endforeach; ?>
</ul>
<?php require '../includes/footer.php'; ?>

Notifications (public/notifications.php)


<?php
session_start();
require '../config/db.php';
require '../includes/header.php';
$user_id = $_SESSION[' user_id'];
$stmt = $conn->prepare(`SELECT * FROM notifications WHERE user_id = ? ORDER BY created_at DESC`);
$stmt->bind_param(`i`, $user_id);
$stmt->execute();
$result = $stmt->get_result();
$notifications = $result->fetch_all(MYSQLI_ASSOC);
?>
<h3>Your Notifications</h3>
<ul class=`list-group`>
    <?php foreach ($notifications as $notification): ?>
    <li class=`list-group-item <?php echo $notification['is_read'] ? 'list-group-item-secondary' : ''; ?>`>
        <?php echo $notification['message']; ?>
        <small class=`text-muted`><?php echo $notification['created_at']; ?></small>
    </li>
    <?php endforeach; ?>
</ul>
<?php require '../includes/footer.php'; ?>

Admin Dashboard (public/admin_dashboard.php)


<?php
session_start();
require '../config/db.php';
require '../includes/header.php';
if (!isset($_SESSION['user_id']) || $_SESSION['role'] !== 'admin') {
    header(`Location: login.php`);
    exit();
}
$stmt = $conn->prepare(`SELECT COUNT(*) AS user_count FROM users`);
$stmt->execute();
$result = $stmt->get_result();
$user_count = $result->fetch_assoc()['user_count'];
$stmt = $conn->prepare(`SELECT COUNT(*) AS post_count FROM posts`);
$stmt->execute();
$result = $stmt->get_result();
$post_count = $result->fetch_assoc()['post_count'];
?>
<h2>Admin Dashboard</h2>
<p>Total Users: <?php echo $user_count; ?></p>
<p>Total Posts: <?php echo $post_count; ?></p>
<?php require '../includes/footer.php'; ?>

6. Additional Features to Consider

User Profiles: Allow users to edit their profiles and manage their settings.

Post Scheduling: Implement functionality for authors to schedule posts for future publication.

Advanced Comment Moderation: Enhance comment management with features for flagging inappropriate comments.

SEO Tools: Provide tools for authors to optimize their posts for search engines.

7. Security Measures

Data Validation: Ensure all user inputs are validated to prevent SQL injection and XSS attacks.

Password Security: Use strong hashing algorithms for storing passwords.

Session Security: Implement secure session management practices to protect user sessions.

8. Testing and Deployment

Unit Testing: Conduct unit tests for individual components to ensure they function correctly.

Integration Testing: Test the integration of different modules to ensure they work together seamlessly.

Deployment: Choose a reliable hosting provider and deploy the application, ensuring all configurations are optimized for performance.

9. Documentation

User Documentation: Create a user manual to guide users through the platform's features and functionalities.

Developer Documentation: Document the codebase and architecture for future reference and maintenance.

10. Future Enhancements

Mobile Application: Develop a mobile application for users to access the platform on the go.

Community Features: Create forums or discussion boards for users to share insights and strategies.

AI-Powered Recommendations: Implement machine learning algorithms to provide personalized content recommendations.

This structured approach will help you build a comprehensive Blogging Platform that meets user needs and adapts to future requirements.

Written by Surfside Media

Senior Full Stack Developer specializing in Web Technologies.