[PHP for Beginners] Developing a Working Web App! Creating a Simple Bulletin Board with Database Integration
In the articles so far, we've learned the basic syntax of PHP, as well as how to retrieve and display data from a database. However, the real fun of web applications comes from the ability for users to "add" or "delete" data, enabling two-way interaction. This "data manipulation by the user" is arguably the core of all web services.
In this article, we will mobilize all the knowledge we've gained so far to develop a full-fledged web application integrated with a database: a simple memo bulletin board. This bulletin board features three basic functions of a web app: posting memos (Create), displaying a list (Read), and deleting them (Delete). The code will be a bit long, but if you copy and paste this single file and run it on your server, you will have your very own "working web application." Please enjoy the immense sense of accomplishment that comes from programming!
To get your PHP running (development environment), if you haven't set up XAMPP yet, please refer to [PHP for Beginners] A Complete Guide to Downloading and Installing XAMPP!. After installation, place your PHP file in the specified folder (like `htdocs`), and you're all set!
1. CRUD: The Basic Design of a Web Application
The web applications we use every day, such as social media, blogs, and e-commerce sites, are fundamentally based on four data operations. These are known by the acronym CRUD.
- Create: To create and post new data.
- Read: To read and display data.
- Update: To update and edit existing data.
- Delete: To delete data.
This time, we will implement three of these functions—C, R, and D, excluding Update (edit)—and take our first step into web application development.
2. In Practice! Developing a Simple Memo Bulletin Board
Alright, let's get right to it. We will implement all the posting, displaying, and deleting functionalities in a single PHP file.
Step A: Preparing the Database and Table
First, we need to create a `memos` table to store the memos. Please execute the following SQL statement in a database management tool like phpMyAdmin.
CREATE TABLE memos (
id INT AUTO_INCREMENT PRIMARY KEY,
content VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Let's add some sample data
INSERT INTO memos (content) VALUES
('Start studying PHP'),
('Think about what to have for dinner tonight'),
('Create a shopping list for the weekend');
Step B: The PHP File with All Functionalities
This is where the real work begins. Please save the following code with a name like `memo.php`. All the database connection information, data addition logic, deletion logic, and display logic are packed into this single file.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Simple Memo Board</title>
<style>
body { font-family: sans-serif; padding: 20px; max-width: 700px; margin: auto; background-color: #f9f9f9; }
h1, h2 { color: #333; border-bottom: 2px solid #007bff; padding-bottom: 10px; }
.memo-form { background: #fff; padding: 20px; border-radius: 8px; margin-bottom: 30px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
textarea { width: 100%; height: 60px; padding: 10px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; margin-bottom: 10px; }
button { padding: 10px 20px; border: none; background-color: #28a745; color: white; border-radius: 4px; cursor: pointer; }
button:hover { background-color: #218838; }
.memo-list { list-style: none; padding: 0; }
.memo-item { background: #fff; padding: 15px; border-left: 5px solid #007bff; margin-bottom: 15px; display: flex; justify-content: space-between; align-items: center; box-shadow: 0 2px 4px rgba(0,0,0,0.05); }
.memo-content { flex-grow: 1; }
.memo-date { font-size: 0.8em; color: #888; display: block; margin-top: 5px; }
.delete-btn { background-color: #dc3545; }
.delete-btn:hover { background-color: #c82333; }
.error-message { color: red; font-weight: bold; }
</style>
</head>
<body>
<h1>Simple Memo Board</h1>
<?php
// --- Database Connection Info ---
$db_host = 'localhost';
$db_name = 'your_database_name';
$db_user = 'your_username';
$db_pass = 'your_password';
try {
$pdo = new PDO("mysql:host={$db_host};dbname={$db_name};charset=utf8", $db_user, $db_pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// --- Data Processing (if POST request) ---
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['action']) && $_POST['action'] === 'add') {
// 【Create】 Add memo process
if (!empty($_POST['content'])) {
$stmt = $pdo->prepare("INSERT INTO memos (content) VALUES (:content)");
$stmt->execute([':content' => $_POST['content']]);
}
} elseif (isset($_POST['action']) && $_POST['action'] === 'delete') {
// 【Delete】 Delete memo process
if (isset($_POST['id'])) {
$stmt = $pdo->prepare("DELETE FROM memos WHERE id = :id");
$stmt->execute([':id' => $_POST['id']]);
}
}
// Redirect to self after processing to prevent double posting
header('Location: ' . $_SERVER['SCRIPT_NAME']);
exit;
}
// --- Data Display (if GET request) ---
// 【Read】 Get memo list
$stmt = $pdo->prepare("SELECT * FROM memos ORDER BY created_at DESC");
$stmt->execute();
$memos = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
echo '<div class="error-message">Database Error: ' . htmlspecialchars($e->getMessage()) . '</div>';
die(); // Terminate script on error
}
?>
<!-- Memo Post Form -->
<section class="memo-form">
<h2>Post a new memo</h2>
<form action="" method="POST">
<input type="hidden" name="action" value="add">
<textarea name="content" required></textarea>
<button type="submit">Post</button>
</form>
</section>
<!-- Memo List Display -->
<section>
<h2>Memo List</h2>
<ul class="memo-list">
<?php if ($memos): ?>
<?php foreach ($memos as $memo): ?>
<li class="memo-item">
<div class="memo-content">
<?php echo htmlspecialchars($memo['content']); ?>
<span class="memo-date">(<?php echo $memo['created_at']; ?>)</span>
</div>
<form action="" method="POST" style="display:inline;">
<input type="hidden" name="action" value="delete">
<input type="hidden" name="id" value="<?php echo $memo['id']; ?>">
<button type="submit" class="delete-btn">Delete</button>
</form>
</li>
<?php endforeach; ?>
<?php else: ?>
<li>No posts yet.</li>
<?php endif; ?>
</ul>
</section>
</body>
</html>
Important: Don't forget to change the database connection information to match your own environment before running this code.
How did it go? You should be able to confirm the series of actions: posting a memo from the form adds it to the list in real-time, and pressing the delete button makes that memo disappear. This is the basic CRUD operation (in this case, CRD) of web application development.
3. Code Explanation and Key Points
This single file of code contains several important techniques.
Mechanism for Handling Everything in One File
This app handles data submission (POST) and page display (GET) in the same file. It uses `if ($_SERVER['REQUEST_METHOD'] === 'POST')` to group the processing for "when the form is submitted." It receives both additions and deletions as POST requests, and after processing, it redirects to itself. This is a technique called the **Post/Redirect/Get (PRG) pattern**, and it's effective in preventing "double posting," where the same data is sent multiple times when the browser's refresh button is pressed.
Utilizing the hidden input type
Both the posting form and the delete button send data to the same file via POST. To distinguish which process is desired, we use `<input type="hidden">`.
In this way, by sending hidden data that is not displayed on the screen, such as "`action`" (what kind of operation) and "`id`" (which memo to target), the PHP side can look at the received data and execute the appropriate process (add or delete).
4. Summary and Next Steps
Great job! This time, we created a dynamic web application, a "Simple Memo Board," that integrates with a database and has Create, Read, and Delete functionalities. The experience of seeing the code you wrote actually work as an "app" in the browser should give you a great sense of accomplishment.
This CRUD concept is the foundation of all web applications. From here, you can further expand the functionality, such as:
- Adding an edit (Update) feature for memos.
- Integrating it with a user login function to make it a personal To-Do list.
- Strengthening the validation of posted content (e.g., character count check).
We encourage you to use this bulletin board as a base to challenge yourself in developing your own original application!