Process php mail and forms
<?php
$errors = [];
$missing = [];
if (isset($_POST['send'])) {
$expected = ['name', 'email', 'comments'];
$required = ['name', 'comments'];
$to = 'David Powers <david@example.com>';
$subject = 'Feedback from online form';
$headers = [];
$headers[] = 'From: webmaster@example.com';
$headers[] = 'Cc: another@example.com';
$headers[] = 'Content-type: text/plain; charset=utf-8';
$authorized = '-fdavid@example.com';
require './includes/process_mail.php';
if ($mailSent) {
header('Location: thanks.php');
exit;
}
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Message body</title>
<link href="styles.css" rel="stylesheet" type="text/css">
</head>
<body>
<h1>Contact Us</h1>
<?php if ($_POST && ($suspect || isset($errors['mailfail']))) : ?>
<p class="warning">Sorry, your mail couldn't be sent.</p>
<?php elseif ($errors || $missing) : ?>
<p class="warning">Please fix the item(s) indicated</p>
<?php endif; ?>
<form method="post" action="<?= $_SERVER['PHP_SELF']; ?>">
<p>
<label for="name">Name:
<?php if ($missing && in_array('name', $missing)) : ?>
<span class="warning">Please enter your name</span>
<?php endif; ?>
</label>
<input type="text" name="name" id="name"
<?php
if ($errors || $missing) {
echo 'value="' . htmlentities($name) . '"';
}
?>
>
</p>
<p>
<label for="email">Email:
<?php if ($missing && in_array('email', $missing)) : ?>
<span class="warning">Please enter your email address</span>
<?php elseif (isset($errors['email'])) : ?>
<span class="warning">Invalid email address</span>
<?php endif; ?>
</label>
<input type="email" name="email" id="email"
<?php
if ($errors || $missing) {
echo 'value="' . htmlentities($email) . '"';
}
?>
>
</p>
<p>
<label for="comments">Comments:
<?php if ($missing && in_array('comments', $missing)) : ?>
<span class="warning">You forgot to add any comments</span>
<?php endif; ?>
</label>
<textarea name="comments" id="comments"><?php
if ($errors || $missing) {
echo htmlentities($comments);
}
?></textarea>
</p>
<p>
<input type="submit" name="send" id="send" value="Send Comments">
</p>
</form>
</body>
</html>
<?php
$mailSent = false;
// Assume the input contains nothing suspect
$suspect = false;
// Regular expression to search for suspect phrases
$pattern = '/Content-type:|Bcc:|Cc:/i';
// Recursive function that checks for suspect phrases
// Third argument is passed by reference
function isSuspect($value, $pattern, &$suspect) {
if (is_array($value)) {
foreach ($value as $item) {
isSuspect($item, $pattern, $suspect);
}
} else {
if (preg_match($pattern, $value)) {
$suspect = true;
}
}
}
// Check the $_POST array for suspect phrases
isSuspect($_POST, $pattern, $suspect);
// Process the form only if no suspect phrases are found
if (!$suspect) :
// Check that required fields have been filled in,
// and reassign expected elements to simple variables
foreach ($_POST as $key => $value) {
$value = is_array($value) ? $value : trim($value);
if (empty($value) && in_array($key, $required)) {
$missing[] = $key;
$$key = '';
} elseif (in_array($key, $expected)) {
$$key = $value;
}
}
// Validate user's email
if (!$missing && !empty($email)) :
$validemail = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if ($validemail) {
$headers[] = "Reply-to: $validemail";
} else {
$errors['email'] = true;
}
endif;
// If no errors, create headers and message body
if (!$errors && !$missing) :
$headers = implode("\r\n", $headers);
// Initialize message
$message = '';
foreach ($expected as $field) :
if (isset($$field) && !empty($$field)) {
$val = $$field;
} else {
$val = 'Not selected';
}
// If an array, expand to a comma-separated string
if (is_array($val)) {
$val = implode(', ', $val);
}
// Replace underscores in the field names with spaces
$field = str_replace('_', ' ', $field);
$message .= ucfirst($field) . ": $val\r\n\r\n";
endforeach;
$message = wordwrap($message, 70);
$mailSent = mail($to, $subject, $message, $headers, $authorized);
if (!$mailSent) {
$errors['mailfail'] = true;
}
endif;
endif;