PHP crash course: Simple Blog Platform

mdarifulhaque

MD ARIFUL HAQUE

Posted on August 2, 2024

PHP crash course: Simple Blog Platform

A basic blogging platform where users can post, edit, and delete articles. Built using PHP, HTML, jQuery, AJAX, JSON, Bootstrap, CSS, and MySQL.

Topics: php, mysql, blog, ajax, bootstrap, jquery, css

Step-by-Step Solution

1. Directory Structure

simple-blog-platform/
│
├── config.sample.php
├── index.html
├── db/
│   └── database.sql
├── src/
│   ├── get-post.php
│   └── post-handler.php
├── include/
│   ├── config.sample.php
│   └── db.php
├── assets/
│   ├── css/
│   │   └── style.css
│   ├── js/
│   │   └── script.js
│   └── images/
├── README.md
└── .gitignore
Enter fullscreen mode Exit fullscreen mode

2. Database Schema

db/database.sql:

CREATE DATABASE IF NOT EXISTS blog_db;
USE blog_db;

CREATE TABLE IF NOT EXISTS posts (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    content TEXT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Enter fullscreen mode Exit fullscreen mode

3. Configuration File

include/config.sample.php:

<?php
define('DB_HOST', 'localhost'); // Database host
define('DB_NAME', 'blog_db'); // Database name
define('DB_USER', 'root'); // Change if necessary
define('DB_PASS', ''); // Change if necessary
?>
Enter fullscreen mode Exit fullscreen mode

4. Configure the Database Connection

include/db.php:

<?php
include 'config.php';

// Database configuration
$dsn = 'mysql:host='.DB_HOST.';dbname='.DB_NAME;
$options = [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];

// Create a new PDO instance
try {
    $pdo = new PDO($dsn, DB_USER, DB_PASS, $options);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Set error mode to exception
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage(); // Display error message if connection fails
}
?>
Enter fullscreen mode Exit fullscreen mode

5. HTML and PHP Structure

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Simple Blog</title>
    <link rel="stylesheet" href="assets/css/style.css">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
    <div class="container">
        <h1 class="mt-5">Simple Blog</h1>
        <div id="posts"></div>
        <button class="btn btn-primary mt-3" data-toggle="modal" data-target="#postModal">Add Post</button>
    </div>

    <!-- Modal for adding/editing posts -->
    <div class="modal fade" id="postModal" tabindex="-1" role="dialog" aria-labelledby="postModalLabel" aria-hidden="true">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="postModalLabel">Add Post</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    <form id="postForm">
                        <input type="hidden" id="postId">
                        <div class="form-group">
                            <label for="title">Title</label>
                            <input type="text" class="form-control" id="title" required>
                        </div>
                        <div class="form-group">
                            <label for="content">Content</label>
                            <textarea class="form-control" id="content" rows="3" required></textarea>
                        </div>
                        <button type="submit" class="btn btn-primary">Save Post</button>
                    </form>
                </div>
            </div>
        </div>
    </div>

    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/js/bootstrap.bundle.min.js"></script>
    <script src="assets/js/script.js"></script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

6. JavaScript and AJAX

assets/js/script.js

$(document).ready(function() {
    // Load posts when the page loads
    loadPosts();

    // Handle form submission
    $('#postForm').submit(function(event) {
        event.preventDefault(); // Prevent default form submission

        var postId = $('#postId').val();
        var title = $('#title').val();
        var content = $('#content').val();

        $.ajax({
            url: 'src/post-handler.php',
            type: 'POST',
            dataType: 'json',
            data: {
                id: postId,
                title: title,
                content: content
            },
            success: function(response) {
                if (response.success) {
                    $('#postModal').modal('hide');
                    loadPosts(); // Reload posts after saving
                } else {
                    alert('Error: ' + response.message);
                }
            }
        });
    });

    // Load posts function
    function loadPosts() {
        $.ajax({
            url: 'src/get-posts.php',
            type: 'GET',
            dataType: 'json',
            success: function(data) {
                var postsHtml = '';
                $.each(data.posts, function(index, post) {
                    postsHtml += '<div class="post"><h2>' + post.title + '</h2><p>' + post.content + '</p></div>';
                });
                $('#posts').html(postsHtml);
            }
        });
    }
});
Enter fullscreen mode Exit fullscreen mode

7. Backend PHP Scripts

src/get-posts.php

<?php
include '../include/db.php';

header('Content-Type: application/json');

try {
    $stmt = $pdo->query('SELECT * FROM posts ORDER BY created_at DESC');
    $posts = $stmt->fetchAll(PDO::FETCH_ASSOC);
    echo json_encode(['posts' => $posts]);
} catch (PDOException $e) {
    echo json_encode(['error' => $e->getMessage()]);
}
?>
Enter fullscreen mode Exit fullscreen mode

src/post-handler.php

<?php
include '../include/db.php';

header('Content-Type: application/json');

// Retrieve POST data
$id = isset($_POST['id']) ? intval($_POST['id']) : 0;
$title = $_POST['title'];
$content = $_POST['content'];

try {
    if ($id > 0) {
        // Update existing post
        $stmt = $pdo->prepare('UPDATE posts SET title = ?, content = ? WHERE id = ?');
        $stmt->execute([$title, $content, $id]);
    } else {
        // Insert new post
        $stmt = $pdo->prepare('INSERT INTO posts (title, content) VALUES (?, ?)');
        $stmt->execute([$title, $content]);
    }
    echo json_encode(['success' => true]);
} catch (PDOException $e) {
    echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
?>
Enter fullscreen mode Exit fullscreen mode

6. CSS Styling

assets/css/style.css

body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 0;
}

.container {
    margin-top: 20px;
}

.post {
    border: 1px solid #ddd;
    padding: 15px;
    margin-bottom: 15px;
    background-color: #f9f9f9;
}
Enter fullscreen mode Exit fullscreen mode

Documentation and Comments

  • config.php: Contains database configuration and connects to MySQL using PDO.
  • index.php: Main page with HTML structure, includes Bootstrap for styling, and a modal for adding/editing posts.
  • assets/js/script.js: Handles AJAX requests for loading and saving posts. Uses jQuery for DOM manipulation and AJAX.
  • get-posts.php: Fetches posts from the database and returns them as JSON.
  • post-handler.php: Handles post creation and updating based on the presence of an ID.

This setup provides a basic blogging platform where users can add and edit posts. You can expand this by adding user authentication, post categories, comments, and more.

Connecting Links

If you found this series helpful, please consider giving the repository a star on GitHub or sharing the post on your favorite social networks 😍. Your support would mean a lot to me!

If you want more helpful content like this, feel free to follow me:

Source Code

💖 💪 🙅 🚩
mdarifulhaque
MD ARIFUL HAQUE

Posted on August 2, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related