[PHP สำหรับผู้เริ่มต้น] การพัฒนาเว็บแอปที่ใช้งานได้จริง! สร้างกระดานข่าวสั้นๆ ด้วยการเชื่อมต่อฐานข้อมูล
ในบทความที่ผ่านมา เราได้เรียนรู้ไวยากรณ์พื้นฐานของ PHP และวิธีดึงข้อมูลจากฐานข้อมูลมาแสดงผลแล้ว แต่ความสนุกที่แท้จริงของการพัฒนาเว็บแอปพลิเคชันนั้น อยู่ที่การที่ผู้ใช้สามารถ "เพิ่ม" หรือ "ลบ" ข้อมูลได้ ซึ่งเป็นการโต้ตอบแบบสองทาง "การจัดการข้อมูลโดยผู้ใช้" นี้เองที่เป็นหัวใจของบริการเว็บทุกประเภท
ในบทความนี้ เราจะรวบรวมความรู้ทั้งหมดที่ผ่านมาเพื่อพัฒนาเว็บแอปพลิเคชันที่ทำงานร่วมกับฐานข้อมูลอย่างเต็มรูปแบบ นั่นคือ กระดานข่าวสำหรับข้อความสั้นๆ กระดานข่าวนี้จะมี 3 ฟังก์ชันพื้นฐานของเว็บแอป ได้แก่ การโพสต์ข้อความ (Create), การแสดงรายการ (Read) และการลบ (Delete) แม้โค้ดจะยาวไปหน่อย แต่ถ้าคุณคัดลอกไฟล์นี้ไปวางและรันบนเซิร์ฟเวอร์ของคุณ คุณก็จะได้ "เว็บแอปพลิเคชันที่ใช้งานได้จริง" เป็นของตัวเอง มาสัมผัสกับความรู้สึกของการประสบความสำเร็จอันยิ่งใหญ่ในการเขียนโปรแกรมกันเถอะครับ!
สำหรับการเตรียมตัวเพื่อรัน PHP (สภาพแวดล้อมการพัฒนา) หากคุณยังไม่ได้ติดตั้ง XAMPP โปรดอ้างอิงจาก [PHP สำหรับผู้เริ่มต้น] คู่มือฉบับสมบูรณ์เกี่ยวกับการดาวน์โหลดและติดตั้ง XAMPP! หลังจากติดตั้งแล้ว เพียงแค่วางไฟล์ PHP ของคุณในโฟลเดอร์ที่กำหนด (เช่น `htdocs`) ก็พร้อมใช้งานแล้วครับ!
1. CRUD: การออกแบบพื้นฐานของเว็บแอปพลิเคชัน
เว็บแอปพลิเคชันที่เราใช้กันอยู่ทุกวัน เช่น โซเชียลมีเดีย, บล็อก, หรือเว็บไซต์อีคอมเมิร์ซ โดยพื้นฐานแล้วประกอบด้วยการจัดการข้อมูล 4 รูปแบบ ซึ่งเรียกโดยใช้ตัวอักษรย่อว่า CRUD (ครัด)
- Create: สร้างและโพสต์ข้อมูลใหม่
- Read: อ่านและแสดงข้อมูล
- Update: อัปเดตและแก้ไขข้อมูลที่มีอยู่
- Delete: ลบข้อมูล
ในครั้งนี้ เราจะมาลองสร้างฟังก์ชัน 3 อย่างคือ C, R, D โดยไม่รวมการแก้ไข (Update) เพื่อเป็นก้าวแรกสู่การพัฒนาเว็บแอปพลิเคชันกันครับ
2. ภาคปฏิบัติ! มาพัฒนากระดานข่าวสั้นๆ กันเถอะ
งั้นเรามาเริ่มสร้างกันเลยครับ เราจะสร้างฟังก์ชันการโพสต์, การแสดงผล, และการลบทั้งหมดไว้ในไฟล์ PHP ไฟล์เดียวกัน
ขั้นตอน A: การเตรียมฐานข้อมูลและตาราง
ก่อนอื่น เราต้องสร้างตาราง `memos` สำหรับเก็บข้อความในฐานข้อมูลก่อน โดยใช้เครื่องมือจัดการฐานข้อมูลอย่าง phpMyAdmin แล้วรันคำสั่ง SQL ต่อไปนี้ครับ
CREATE TABLE memos (
id INT AUTO_INCREMENT PRIMARY KEY,
content VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- ลองใส่ข้อมูลตัวอย่างลงไปสักหน่อย
INSERT INTO memos (content) VALUES
('เริ่มเรียน PHP'),
('คิดเมนูอาหารเย็นวันนี้'),
('ทำรายการของที่จะซื้อสุดสัปดาห์นี้');
ขั้นตอน B: ไฟล์ PHP ที่รวมทุกฟังก์ชัน
จากนี้ไปคือของจริงครับ ให้บันทึกโค้ดต่อไปนี้เป็นชื่อไฟล์เช่น `memo.php` ซึ่งในไฟล์เดียวนี้จะมีทั้งข้อมูลการเชื่อมต่อฐานข้อมูล, ตรรกะการเพิ่มข้อมูล, ตรรกะการลบ, และตรรกะการแสดงผลทั้งหมดรวมอยู่ด้วยกัน
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<title>กระดานข่าวสั้นๆ</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>กระดานข่าวสั้นๆ</h1>
<?php
// --- ข้อมูลการเชื่อมต่อฐานข้อมูล ---
$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);
// --- การประมวลผลข้อมูล (กรณีมี request แบบ POST) ---
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['action']) && $_POST['action'] === 'add') {
// 【Create】 การประมวลผลเพิ่มข้อความ
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】 การประมวลผลลบข้อความ
if (isset($_POST['id'])) {
$stmt = $pdo->prepare("DELETE FROM memos WHERE id = :id");
$stmt->execute([':id' => $_POST['id']]);
}
}
// หลังจากประมวลผลแล้ว ให้ redirect มาที่ตัวเองเพื่อป้องกันการโพสต์ซ้ำ
header('Location: ' . $_SERVER['SCRIPT_NAME']);
exit;
}
// --- การแสดงผลข้อมูล (กรณีมี request แบบ GET) ---
// 【Read】 ดึงรายการข้อความ
$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">ข้อผิดพลาดฐานข้อมูล: ' . htmlspecialchars($e->getMessage()) . '</div>';
die(); // หยุดการทำงานเมื่อเกิดข้อผิดพลาด
}
?>
<!-- ฟอร์มโพสต์ข้อความ -->
<section class="memo-form">
<h2>โพสต์ข้อความใหม่</h2>
<form action="" method="POST">
<input type="hidden" name="action" value="add">
<textarea name="content" required></textarea>
<button type="submit">โพสต์</button>
</form>
</section>
<!-- แสดงรายการข้อความ -->
<section>
<h2>รายการข้อความ</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">ลบ</button>
</form>
</li>
<?php endforeach; ?>
<?php else: ?>
<li>ยังไม่มีโพสต์</li>
<?php endif; ?>
</ul>
</section>
</body>
</html>
สำคัญ: อย่าลืมแก้ไขข้อมูลการเชื่อมต่อฐานข้อมูลให้ตรงกับสภาพแวดล้อมของคุณก่อนรันโค้ดนี้นะครับ
เป็นอย่างไรบ้างครับ? คุณน่าจะสามารถยืนยันการทำงานทั้งหมดได้แล้ว คือเมื่อโพสต์ข้อความจากฟอร์ม ข้อความนั้นจะถูกเพิ่มเข้าไปในรายการแบบเรียลไทม์ และเมื่อกดปุ่มลบ ข้อความนั้นก็จะหายไป นี่คือการทำงานพื้นฐานของ CRUD (ในที่นี้คือ CRD) ในการพัฒนาเว็บแอปพลิเคชันครับ
3. คำอธิบายโค้ดและประเด็นสำคัญ
ในโค้ดไฟล์เดียวนี้ มีเทคนิคสำคัญๆ อยู่หลายอย่างครับ
กลไกการประมวลผลทุกอย่างในไฟล์เดียว
แอปนี้จัดการทั้งการส่งข้อมูล (POST) และการแสดงผลหน้าเว็บ (GET) ในไฟล์เดียวกัน โดยใช้ `if ($_SERVER['REQUEST_METHOD'] === 'POST')` เพื่อรวบรวมการประมวลผล "เมื่อมีการส่งฟอร์ม" ครับ ทั้งการเพิ่มและการลบจะถูกรับมาเป็น request แบบ POST และเมื่อประมวลผลเสร็จแล้วก็จะ redirect กลับมาที่ตัวเอง เทคนิคนี้เรียกว่า **Post/Redirect/Get (PRG) Pattern** ซึ่งมีผลช่วยป้องกัน "การโพสต์ซ้ำ" ที่เกิดจากการกดปุ่มรีเฟรชของเบราว์เซอร์แล้วข้อมูลเดิมถูกส่งไปซ้ำๆ
การใช้ input type="hidden"
ทั้งฟอร์มโพสต์และปุ่มลบต่างก็ส่งข้อมูลไปยังไฟล์เดียวกันด้วยวิธี POST เพื่อที่จะแยกแยะได้ว่าต้องการให้ประมวลผลอะไร เราจึงใช้ `<input type="hidden">` ครับ
ด้วยวิธีนี้ การส่งข้อมูลที่ซ่อนไว้ซึ่งไม่แสดงบนหน้าจอ เช่น "`action` (เป็นการกระทำอะไร)" หรือ "`id` (จะกระทำกับข้อความไหน)" ไปพร้อมกัน จะทำให้ฝั่ง PHP สามารถดูข้อมูลที่ได้รับแล้วทำการประมวลผลที่เหมาะสม (เพิ่ม หรือ ลบ) ได้นั่นเอง
4. สรุปและขั้นตอนต่อไป
お疲れ様でした!今回は、データベースと連携し、データの作成(Create)、読み込み(Read)、削除(Delete)の機能を持つ、動的なWebアプリケーション「一言メモ掲示板」を作成しました。自分の書いたコードがブラウザ上で実際に「アプリ」として動く体験は、大きな自信に繋がったのではないでしょうか。
このCRUDの考え方は、あらゆるWebアプリケーションの基礎となります。ここからさらに、
- การเพิ่มฟังก์ชันแก้ไขข้อความ (Update)
- การเชื่อมต่อกับฟังก์ชันล็อกอินของผู้ใช้แต่ละคน เพื่อสร้างเป็น ToDo List ส่วนตัว
- การเพิ่มความแข็งแกร่งให้กับการตรวจสอบข้อมูลที่โพสต์ (เช่น การตรวจสอบจำนวนตัวอักษร)
คุณสามารถขยายฟังก์ชันการทำงานในรูปแบบเหล่านี้ต่อไปได้ ลองใช้กระดานข่าวนี้เป็นพื้นฐานแล้วท้าทายตัวเองในการพัฒนาแอปพลิเคชันที่เป็นออริจินัลของคุณดูนะครับ!