ทำไมต้องมี Contact Form?
ทุกเว็บไซต์ที่ต้องการรับ Feedback หรือสอบถามจากผู้ใช้ จำเป็นต้องมีหน้า "ติดต่อเรา" วิธีดั้งเดิมคือให้แสดง Email Address ตรงๆ แต่มีปัญหาเรื่อง Spam Bot มาดูดเอาไปใช้ แนวทางที่ดีกว่าคือใช้ PHP Contact Form — ผู้ใช้กรอกข้อมูลในหน้าเว็บ แล้วให้ PHP จัดการส่ง Email ให้เบื้องหลัง
บทความนี้จะสอนสร้าง Contact Form แบบ ไม่พึ่งฐานข้อมูล โค้ดเบาสุด ติดตั้งง่าย เหมาะสำหรับเว็บไซต์ขนาดเล็กหรือ Landing Page และยังเป็นพื้นฐานที่จะต่อยอดเข้า CodeIgniter 4 หรือ Laravel ได้ในภายหลัง
สิ่งที่จะได้เรียนรู้: HTML Form → PHP $_POST → Validation → mail() function → แสดง Success/Error Message
Step 1 — สร้าง HTML Form
เริ่มด้วยไฟล์ contact.html (หรือ contact.php) ที่มี Form รับชื่อ, Email และข้อความ สังเกต attribute สำคัญ 2 ตัวบน <form>:
method="POST" — ซ่อนข้อมูลใน Request Body ไม่โชว์ใน URLaction="send.php" — ส่งข้อมูลไปประมวลผลที่ไฟล์นี้
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<title>ติดต่อเรา</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
</head>
<body class="bg-light py-5">
<div class="container" style="max-width:560px">
<h2 class="mb-4">ติดต่อเรา</h2>
<form method="POST" action="send.php">
<div class="mb-3">
<label class="form-label">ชื่อ-นามสกุล</label>
<input type="text" name="name"
class="form-control"
placeholder="กรอกชื่อของคุณ"
required>
</div>
<div class="mb-3">
<label class="form-label">อีเมล</label>
<input type="email" name="email"
class="form-control"
placeholder="example@email.com"
required>
</div>
<div class="mb-3">
<label class="form-label">ข้อความ</label>
<textarea name="message"
class="form-control"
rows="5"
placeholder="พิมพ์ข้อความของคุณ..."
required></textarea>
</div>
<button type="submit" class="btn btn-primary w-100">
ส่งข้อความ
</button>
</form>
</div>
</body></html>Step 2 — สร้าง PHP Handler (send.php)
นี่คือหัวใจหลักของระบบ ไฟล์ send.php จะรับค่าจาก $_POST, Validate ข้อมูล, แล้วใช้ฟังก์ชัน mail() ส่ง Email ไปยังกล่องจดหมายของเรา
<?php
// ป้องกัน Direct Access (ต้องมาจาก POST เท่านั้น)
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header('Location: contact.php');
exit();
}
// 1. รับค่าและทำความสะอาดข้อมูล (Sanitize)
$name = trim(htmlspecialchars(strip_tags($_POST['name'])));
$email = trim(filter_var($_POST['email'], FILTER_SANITIZE_EMAIL));
$message = trim(htmlspecialchars(strip_tags($_POST['message'])));
// 2. Validate ข้อมูล
$errors = [];
if (empty($name)) {
$errors[] = 'กรุณากรอกชื่อ';
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = 'รูปแบบอีเมลไม่ถูกต้อง';
}
if (strlen($message) < 10) {
$errors[] = 'ข้อความต้องมีอย่างน้อย 10 ตัวอักษร';
}
// 3. ถ้า Validate ไม่ผ่าน — แสดง Error แล้วหยุด
if (!empty($errors)) {
foreach ($errors as $err) {
echo "<p style='color:red'>" . $err . "</p>";
}
exit();
}
// 4. เตรียม Email
$to = 'your@email.com'; // เปลี่ยนเป็น Email ของคุณ
$subject = '[Contact Form] ข้อความจาก ' . $name;
$body = "ชื่อ: {$name}\n"
. "อีเมล: {$email}\n\n"
. "ข้อความ:\n{$message}";
$headers = implode("\r\n", [
'From: noreply@yoursite.com',
'Reply-To: ' . $email,
'Content-Type: text/plain; charset=UTF-8',
'X-Mailer: PHP/' . phpversion(),
]);
// 5. ส่ง Email
if (mail($to, $subject, $body, $headers)) {
echo '<p style="color:green">✅ ส่งข้อความสำเร็จ! เราจะติดต่อกลับเร็วๆ นี้</p>';
} else {
echo '<p style="color:red">❌ เกิดข้อผิดพลาด ไม่สามารถส่งได้ กรุณาลองใหม่</p>';
}
?>⚠️ หมายเหตุ: ฟังก์ชัน mail() ต้องมีการตั้งค่า SMTP บน Server ให้ถูกต้อง บน Localhost (XAMPP/Laragon) อาจต้องใช้ PHPMailer + Gmail SMTP แทน — จะอธิบายใน Step 4
Step 3 — Security: ป้องกัน XSS และ Header Injection
Contact Form ที่ไม่ได้ป้องกันเลยมีความเสี่ยง 2 อย่างหลัก:
XSS (Cross-Site Scripting)
ผู้ไม่หวังดีอาจส่ง <script>alert('hacked')</script> เข้ามาในช่องข้อความ แก้ด้วยการใช้ htmlspecialchars() และ strip_tags() ก่อนนำไปแสดงผล
Email Header Injection
ถ้าเอา $email ที่รับมาใส่ใน Header โดยตรงโดยไม่ Sanitize อาจถูก Inject Header เพิ่มได้ โค้ดข้างบนใช้ FILTER_SANITIZE_EMAIL เพื่อตัดอักขระที่ไม่ถูกต้องออก
// ✅ Safe — ใช้ filter functions ก่อนเสมอ
$name = trim(htmlspecialchars(strip_tags($_POST['name'])));
$email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
// ❌ Unsafe — อย่าทำแบบนี้
$name = $_POST['name']; // ไม่ได้ Sanitize เลย
$email = $_POST['email']; // เสี่ยง Header Injection
Step 4 — ใช้ PHPMailer แทน mail() (แนะนำ)
ฟังก์ชัน mail() แบบ Built-in ใช้ได้บน Shared Hosting ทั่วไป แต่ถ้าต้องการส่งผ่าน Gmail SMTP หรือ Service อื่นเช่น SendGrid, Mailgun ควรใช้ PHPMailer ซึ่งติดตั้งผ่าน Composer ได้เลย
composer require phpmailer/phpmailer
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'vendor/autoload.php';
$mail = new PHPMailer(true);
try {
// SMTP Settings
$mail->isSMTP();
$mail->Host = 'smtp.gmail.com';
$mail->SMTPAuth = true;
$mail->Username = 'your@gmail.com';
$mail->Password = 'app-password-here'; // App Password จาก Google
$mail->SMTPSecure = 'tls';
$mail->Port = 587;
$mail->CharSet = 'UTF-8';
// ผู้ส่ง/ผู้รับ
$mail->setFrom('noreply@yoursite.com', 'My Website');
$mail->addAddress('your@email.com');
$mail->addReplyTo($email, $name);
// เนื้อหา Email
$mail->Subject = '[Contact] ข้อความจาก ' . $name;
$mail->Body = "ชื่อ: {$name}\nEmail: {$email}\n\n{$message}";
$mail->send();
echo '✅ ส่งสำเร็จแล้ว!';
} catch (Exception $e) {
echo "❌ Error: {$mail->ErrorInfo}";
}เปรียบเทียบ mail() vs PHPMailer
| Feature | mail() Built-in | PHPMailer |
|---|
| ติดตั้ง | ไม่ต้องติดตั้ง มีใน PHP ทันที | ต้องติดตั้งผ่าน Composer |
| SMTP Auth | ❌ ไม่รองรับโดยตรง | ✅ รองรับเต็มรูปแบบ |
| Gmail/SendGrid | ❌ ต้องตั้งค่า Server เอง | ✅ ใช้งานได้ทันที |
| HTML Email | ทำได้ แต่ยุ่งยาก | ✅ ง่ายมาก รองรับ Attachment ด้วย |
| Error Handling | คืนแค่ true/false | ✅ มี Exception พร้อม Error Message |
| เหมาะกับ | Shared Hosting ทั่วไป | ทุก Environment โดยเฉพาะ Production |
ต่อยอดเข้า CodeIgniter 4 และ Laravel
ถ้าใช้ Framework อยู่แล้ว ไม่จำเป็นต้องเขียน send.php แยกออกมา ทั้ง CI4 และ Laravel มีโครงสร้างที่รองรับการทำ Contact Form ได้สวยงามกว่า:
CodeIgniter 4
<?php
namespace App\Controllers;
use CodeIgniter\Controller;
class ContactController extends Controller
{
public function send()
{
$rules = [
'name' => 'required|min_length[2]',
'email' => 'required|valid_email',
'message' => 'required|min_length[10]',
];
if (!$this->validate($rules)) {
return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
}
$email = service('email');
$email->setTo('your@email.com');
$email->setSubject('Contact: ' . $this->request->getPost('name'));
$email->setMessage($this->request->getPost('message'));
$email->send();
return redirect()->to('/contact')->with('success', 'ส่งข้อความสำเร็จ!');
}
}Laravel (Mailable)
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Mail\ContactMail;
public function send(Request $request)
{
$validated = $request->validate([
'name' => 'required|string|max:100',
'email' => 'required|email',
'message' => 'required|min:10',
]);
Mail::to('your@email.com')->send(new ContactMail($validated));
return back()->with('success', 'ขอบคุณ! เราจะติดต่อกลับเร็วๆ นี้');
}💡 เคล็ดลับ: ใน Laravel ใช้คำสั่ง php artisan make:mail ContactMail เพื่อสร้าง Mailable Class พร้อม Blade Template อัตโนมัติ สะอาดกว่าการ Hard-code HTML ใน Controller มาก
สรุป
Contact Form แบบ Lightweight ที่ไม่ใช้ฐานข้อมูลเป็นจุดเริ่มต้นที่ดีมากสำหรับมือใหม่ แค่ 2 ไฟล์ (contact.php + send.php) ก็พร้อมใช้งานจริงบน Server แล้ว
ขั้นตอนสำคัญที่ต้องจำ:
1รับค่าจาก $_POST แล้ว Sanitize ทันที
2Validate ทุก Field ก่อนดำเนินการต่อ
3ใช้ mail() สำหรับ Hosting ทั่วไป หรือ PHPMailer สำหรับ SMTP
4แสดง Success/Error Message ให้ผู้ใช้รู้ผลทันที
5ต่อยอดเข้า CI4 หรือ Laravel ด้วย Built-in Email Service
อ่านบทความ PHP เพิ่มเติมที่ PHP Code Mania