Simple Blog PlatformPHP, MySQL
👤 Sharing: AI
```php
<?php
// Database configuration
$host = 'localhost';
$username = 'your_username'; // Replace with your MySQL username
$password = 'your_password'; // Replace with your MySQL password
$database = 'your_database'; // Replace with your database name
// Establish database connection
try {
$db = new PDO("mysql:host=$host;dbname=$database;charset=utf8", $username, $password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Database connection failed: " . $e->getMessage());
}
// --- Helper Functions ---
function escape($html) {
return htmlspecialchars($html, ENT_QUOTES, 'UTF-8');
}
// --- Routing and Controller Logic ---
$action = isset($_GET['action']) ? $_GET['action'] : 'home';
switch ($action) {
case 'home':
include 'controllers/home_controller.php';
break;
case 'post':
include 'controllers/post_controller.php';
break;
case 'create':
include 'controllers/create_controller.php';
break;
case 'edit':
include 'controllers/edit_controller.php';
break;
case 'delete':
include 'controllers/delete_controller.php';
break;
default:
include 'controllers/404_controller.php';
break;
}
?>
```
**controllers/home_controller.php:**
```php
<?php
// Fetch all blog posts
$stmt = $db->query("SELECT id, title, content, created_at FROM posts ORDER BY created_at DESC");
$posts = $stmt->fetchAll(PDO::FETCH_ASSOC);
include 'views/home.php';
?>
```
**controllers/post_controller.php:**
```php
<?php
if (isset($_GET['id']) && is_numeric($_GET['id'])) {
$postId = (int)$_GET['id'];
$stmt = $db->prepare("SELECT id, title, content, created_at FROM posts WHERE id = ?");
$stmt->execute([$postId]);
$post = $stmt->fetch(PDO::FETCH_ASSOC);
if ($post) {
include 'views/post.php';
} else {
include 'controllers/404_controller.php';
}
} else {
include 'controllers/404_controller.php';
}
?>
```
**controllers/create_controller.php:**
```php
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$title = isset($_POST['title']) ? trim($_POST['title']) : '';
$content = isset($_POST['content']) ? trim($_POST['content']) : '';
if (empty($title) || empty($content)) {
$error = "Title and content are required.";
include 'views/create.php';
} else {
try {
$stmt = $db->prepare("INSERT INTO posts (title, content, created_at) VALUES (?, ?, NOW())");
$stmt->execute([$title, $content]);
header("Location: index.php"); // Redirect to homepage
exit();
} catch (PDOException $e) {
$error = "Error creating post: " . $e->getMessage();
include 'views/create.php';
}
}
} else {
include 'views/create.php';
}
?>
```
**controllers/edit_controller.php:**
```php
<?php
if (isset($_GET['id']) && is_numeric($_GET['id'])) {
$postId = (int)$_GET['id'];
// Fetch the post to edit
$stmt = $db->prepare("SELECT id, title, content FROM posts WHERE id = ?");
$stmt->execute([$postId]);
$post = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$post) {
include 'controllers/404_controller.php';
exit();
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$title = isset($_POST['title']) ? trim($_POST['title']) : '';
$content = isset($_POST['content']) ? trim($_POST['content']) : '';
if (empty($title) || empty($content)) {
$error = "Title and content are required.";
} else {
try {
$stmt = $db->prepare("UPDATE posts SET title = ?, content = ? WHERE id = ?");
$stmt->execute([$title, $content, $postId]);
header("Location: index.php?action=post&id=" . $postId); // Redirect to updated post
exit();
} catch (PDOException $e) {
$error = "Error updating post: " . $e->getMessage();
}
}
}
include 'views/edit.php';
} else {
include 'controllers/404_controller.php';
}
?>
```
**controllers/delete_controller.php:**
```php
<?php
if (isset($_GET['id']) && is_numeric($_GET['id'])) {
$postId = (int)$_GET['id'];
// Confirm deletion (optional: you could add a confirmation page)
try {
$stmt = $db->prepare("DELETE FROM posts WHERE id = ?");
$stmt->execute([$postId]);
header("Location: index.php"); // Redirect to homepage
exit();
} catch (PDOException $e) {
die("Error deleting post: " . $e->getMessage()); // Handle error more gracefully in a real app.
}
} else {
include 'controllers/404_controller.php';
}
?>
```
**controllers/404_controller.php:**
```php
<?php
$title = "Page Not Found";
include 'views/404.php';
?>
```
**views/home.php:**
```php
<!DOCTYPE html>
<html>
<head>
<title>Simple Blog</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<header>
<h1>Simple Blog</h1>
<nav>
<a href="index.php">Home</a> | <a href="index.php?action=create">Create New Post</a>
</nav>
</header>
<main>
<?php if (empty($posts)): ?>
<p>No posts yet. <a href="index.php?action=create">Create the first one!</a></p>
<?php else: ?>
<?php foreach ($posts as $post): ?>
<article>
<h2><a href="index.php?action=post&id=<?php echo escape($post['id']); ?>"><?php echo escape($post['title']); ?></a></h2>
<p class="date">Posted on <?php echo escape(date('F j, Y', strtotime($post['created_at']))); ?></p>
<p><?php echo substr(escape($post['content']), 0, 200); ?>...</p>
<p><a href="index.php?action=post&id=<?php echo escape($post['id']); ?>">Read More</a> | <a href="index.php?action=edit&id=<?php echo escape($post['id']); ?>">Edit</a> | <a href="index.php?action=delete&id=<?php echo escape($post['id']); ?>" onclick="return confirm('Are you sure you want to delete this post?')">Delete</a></p>
</article>
<?php endforeach; ?>
<?php endif; ?>
</main>
<footer>
<p>© <?php echo date('Y'); ?> Simple Blog</p>
</footer>
</body>
</html>
```
**views/post.php:**
```php
<!DOCTYPE html>
<html>
<head>
<title><?php echo escape($post['title']); ?> - Simple Blog</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<header>
<h1>Simple Blog</h1>
<nav>
<a href="index.php">Home</a> | <a href="index.php?action=create">Create New Post</a>
</nav>
</header>
<main>
<article>
<h2><?php echo escape($post['title']); ?></h2>
<p class="date">Posted on <?php echo escape(date('F j, Y', strtotime($post['created_at']))); ?></p>
<p><?php echo escape($post['content']); ?></p>
<p><a href="index.php?action=edit&id=<?php echo escape($post['id']); ?>">Edit</a> | <a href="index.php?action=delete&id=<?php echo escape($post['id']); ?>" onclick="return confirm('Are you sure you want to delete this post?')">Delete</a></p>
</article>
<a href="index.php">Back to Home</a>
</main>
<footer>
<p>© <?php echo date('Y'); ?> Simple Blog</p>
</footer>
</body>
</html>
```
**views/create.php:**
```php
<!DOCTYPE html>
<html>
<head>
<title>Create New Post - Simple Blog</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<header>
<h1>Simple Blog</h1>
<nav>
<a href="index.php">Home</a> | <a href="index.php?action=create">Create New Post</a>
</nav>
</header>
<main>
<h2>Create New Post</h2>
<?php if (isset($error)): ?>
<p class="error"><?php echo escape($error); ?></p>
<?php endif; ?>
<form method="post" action="index.php?action=create">
<label for="title">Title:</label><br>
<input type="text" id="title" name="title" required><br><br>
<label for="content">Content:</label><br>
<textarea id="content" name="content" rows="10" cols="50" required></textarea><br><br>
<button type="submit">Publish</button>
</form>
<a href="index.php">Back to Home</a>
</main>
<footer>
<p>© <?php echo date('Y'); ?> Simple Blog</p>
</footer>
</body>
</html>
```
**views/edit.php:**
```php
<!DOCTYPE html>
<html>
<head>
<title>Edit Post - Simple Blog</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<header>
<h1>Simple Blog</h1>
<nav>
<a href="index.php">Home</a> | <a href="index.php?action=create">Create New Post</a>
</nav>
</header>
<main>
<h2>Edit Post</h2>
<?php if (isset($error)): ?>
<p class="error"><?php echo escape($error); ?></p>
<?php endif; ?>
<form method="post" action="index.php?action=edit&id=<?php echo escape($post['id']); ?>">
<label for="title">Title:</label><br>
<input type="text" id="title" name="title" value="<?php echo escape($post['title']); ?>" required><br><br>
<label for="content">Content:</label><br>
<textarea id="content" name="content" rows="10" cols="50" required><?php echo escape($post['content']); ?></textarea><br><br>
<button type="submit">Update</button>
</form>
<a href="index.php?action=post&id=<?php echo escape($post['id']); ?>">Back to Post</a> | <a href="index.php">Back to Home</a>
</main>
<footer>
<p>© <?php echo date('Y'); ?> Simple Blog</p>
</footer>
</body>
</html>
```
**views/404.php:**
```php
<!DOCTYPE html>
<html>
<head>
<title><?php echo escape($title); ?> - Simple Blog</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<header>
<h1>Simple Blog</h1>
<nav>
<a href="index.php">Home</a> | <a href="index.php?action=create">Create New Post</a>
</nav>
</header>
<main>
<h2><?php echo escape($title); ?></h2>
<p>Sorry, the page you requested could not be found.</p>
<a href="index.php">Back to Home</a>
</main>
<footer>
<p>© <?php echo date('Y'); ?> Simple Blog</p>
</footer>
</body>
</html>
```
**css/style.css:**
```css
body {
font-family: sans-serif;
margin: 20px;
line-height: 1.6;
}
header {
background-color: #f0f0f0;
padding: 10px;
text-align: center;
margin-bottom: 20px;
}
nav a {
margin: 0 10px;
}
main {
max-width: 800px;
margin: 0 auto;
}
article {
margin-bottom: 30px;
padding: 15px;
border: 1px solid #ddd;
}
article h2 a {
text-decoration: none;
color: #333;
}
.date {
font-style: italic;
color: #777;
margin-bottom: 10px;
}
footer {
text-align: center;
margin-top: 30px;
padding-top: 10px;
border-top: 1px solid #ddd;
}
.error {
color: red;
}
```
**Database Setup:**
1. **Create a Database:** In your MySQL environment (e.g., phpMyAdmin, MySQL Workbench), create a database named `your_database` (or whatever you specified in `$database`).
2. **Create the `posts` table:** Execute the following SQL query in your database:
```sql
CREATE TABLE posts (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
created_at DATETIME NOT NULL
);
```
**Key Improvements and Explanations:**
* **PDO for Database Interaction:** Uses PDO (PHP Data Objects) for database interaction. PDO provides a consistent interface to access different databases and supports prepared statements, which help prevent SQL injection vulnerabilities.
* **Error Handling:** Includes basic error handling using `try...catch` blocks for database operations. A more robust application would log errors and handle them more gracefully.
* **Prepared Statements:** Uses prepared statements with placeholders (e.g., `?`) to prevent SQL injection. The values are bound separately using `$stmt->execute()`.
* **Input Validation and Sanitization:** `trim()` is used to remove whitespace from user inputs. `htmlspecialchars()` with `ENT_QUOTES` is used to escape HTML entities, preventing XSS (Cross-Site Scripting) vulnerabilities. It is vital to ALWAYS sanitize user input.
* **Clear Routing:** Uses a simple routing system based on the `action` GET parameter. This makes the code more organized and easier to maintain.
* **Controller-View Separation:** Separates the application logic (controllers) from the presentation (views). This follows the MVC (Model-View-Controller) pattern, improving code organization and maintainability.
* **Includes:** Uses `include` statements to include the appropriate controller and view files.
* **`escape()` function:** Creates a reusable helper function to escape output for HTML. This makes the code more DRY (Don't Repeat Yourself) and easier to read.
* **CSS Styling:** Includes a basic `style.css` file to provide some basic styling.
* **Delete Confirmation:** Includes a JavaScript confirmation dialog before deleting a post to prevent accidental deletions.
* **Clearer File Structure:** Uses separate directories for controllers (`controllers/`) and views (`views/`). This makes the project structure more organized.
* **Error Messages:** Provides more informative error messages to the user.
* **Redirects:** Uses `header("Location: ...")` to redirect the user after successful form submissions. `exit()` is called after `header()` to prevent further script execution.
* **404 Handling:** Includes a 404 (Page Not Found) controller and view.
* **`created_at` field:** The `posts` table now includes a `created_at` field to store the date and time when the post was created, allowing for sorting by date.
* **Improved Comments:** Added more comments to explain the code.
* **`substr()` for Home Page Excerpt:** Uses `substr()` on the home page to create a short excerpt of the post content.
* **Back to Home Links:** Added "Back to Home" links for easier navigation.
* **No sessions or user authentication:** This is a *very* basic blog. It has no user authentication. Adding that would significantly increase the complexity. You'd need to hash passwords, store sessions, etc.
* **No image uploading:** This only handles text-based posts.
**How to Run:**
1. **Save the Files:** Save the code into separate files in your web server's document root (e.g., `/var/www/html/` or `C:\xampp\htdocs\`) with the specified names (e.g., `index.php`, `controllers/home_controller.php`, `views/home.php`, `css/style.css`). Create the `controllers` and `views` directories.
2. **Configure Database:** Update the database connection details in `index.php` with your MySQL username, password, and database name.
3. **Create Database and Table:** Create the database and the `posts` table using the SQL query provided above.
4. **Access in Browser:** Open your web browser and go to `http://localhost/` (or the appropriate URL for your web server).
**Important Security Considerations:**
* **SQL Injection:** The code *attempts* to prevent SQL injection by using prepared statements. However, always be vigilant and double-check that all user inputs are properly sanitized and validated.
* **XSS (Cross-Site Scripting):** The code uses `htmlspecialchars()` to escape output for HTML. Make sure you escape *all* user-generated content that is displayed on the page.
* **CSRF (Cross-Site Request Forgery):** For a more secure application, you should implement CSRF protection, especially for forms that modify data (e.g., create, edit, delete).
* **User Authentication:** This example does *not* include user authentication. If you need user accounts, you'll need to implement a secure authentication system.
* **Error Handling:** The error handling is basic. In a production environment, you should log errors and handle them more gracefully, without exposing sensitive information to the user.
* **File Uploads:** This example does not handle file uploads. If you need to allow users to upload files, you must implement strict security measures to prevent malicious uploads.
This complete example provides a functional, albeit basic, blog platform. Remember to address the security considerations before deploying this code to a production environment. It's a starting point; you can expand upon it to add more features and improve security.
👁️ Viewed: 29
Comments