PHP Contact Form Handler
Backend Integration
Source: 16idc
A secure PHP contact form handler with input validation, CSRF protection, email sanitization, and AJAX JSON response support.
Secure Contact Form Endpoint
<?php
// contact.php — Secure contact form handler
// Supports both regular POST and AJAX JSON requests
header('Content-Type: application/json');
// === Configuration ===
$to_email = '[email protected]';
$site_name = 'Your Website';
$secret_key = 'your-csrf-secret'; // Change this!
// === CSRF Protection ===
session_start();
if (!isset($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
// === Rate Limiting (session-based) ===
$rate_limit = 3; // Max submissions per hour
$rate_window = 3600; // 1 hour in seconds
if (!isset($_SESSION['submit_count'])) {
$_SESSION['submit_count'] = 1;
$_SESSION['submit_time'] = time();
} elseif (time() - $_SESSION['submit_time'] < $rate_window) {
$_SESSION['submit_count']++;
if ($_SESSION['submit_count'] > $rate_limit) {
http_response_code(429);
die(json_encode(['error' => 'Too many requests. Please try again later.']));
}
} else {
$_SESSION['submit_count'] = 1;
$_SESSION['submit_time'] = time();
}
// === Parse Input ===
$input = $_SERVER['CONTENT_TYPE'] === 'application/json'
? json_decode(file_get_contents('php://input'), true)
: $_POST;
// === Validate CSRF Token ===
if (!isset($input['csrf_token']) || $input['csrf_token'] !== $_SESSION['csrf_token']) {
http_response_code(403);
die(json_encode(['error' => 'Invalid session. Please refresh the page.']));
}
// === Validate Input Fields ===
$errors = [];
$name = trim($input['name'] ?? '');
if (strlen($name) < 2 || strlen($name) > 100) {
$errors[] = 'Name must be between 2 and 100 characters.';
}
$email = filter_var($input['email'] ?? '', FILTER_VALIDATE_EMAIL);
if (!$email) {
$errors[] = 'Please enter a valid email address.';
}
$message = trim($input['message'] ?? '');
if (strlen($message) < 10 || strlen($message) > 5000) {
$errors[] = 'Message must be between 10 and 5000 characters.';
}
if (!empty($errors)) {
http_response_code(422);
die(json_encode(['error' => implode(' ', $errors)]));
}
// === Honeypot Check (anti-spam) ===
if (!empty($input['website'])) {
// Bot filled hidden field
http_response_code(200);
die(json_encode(['success' => true, 'message' => 'Thank you!'])); // Silent reject
}
// === Send Email ===
$subject = sprintf('[%s] New inquiry from %s', $site_name, $name);
$body = "Name: $name\nEmail: $email\n\nMessage:\n$message";
$headers = "From: $name <$email>\r\nReply-To: $email\r\n";
$headers .= "X-Mailer: PHP/" . phpversion();
if (mail($to_email, $subject, $body, $headers)) {
echo json_encode(['success' => true, 'message' => 'Thank you! We will get back to you soon.']);
} else {
http_response_code(500);
echo json_encode(['error' => 'Failed to send message. Please try again later.']);
}
?>
Frontend Form HTML
<form id="contactForm" method="POST" action="contact.php">
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
<input type="hidden" name="website" style="display:none" tabindex="-1" autocomplete="off">
<div>
<label for="name">Name</label>
<input type="text" name="name" id="name" required minlength="2">
</div>
<div>
<label for="email">Email</label>
<input type="email" name="email" id="email" required>
</div>
<div>
<label for="message">Message</label>
<textarea name="message" id="message" required minlength="10"></textarea>
</div>
<button type="submit">Send Message</button>
<div id="formStatus"></div>
</form>
Security Features
- ✅ CSRF token protection
- ✅ Rate limiting (3 submissions/hour)
- ✅ Input validation & sanitization
- ✅ Honeypot anti-spam field
- ✅ Prepared email headers (prevent injection)
- ✅ JSON error responses for AJAX
- ✅ Session-based rate limiting