marc walter

Feedback form with mail in PHP

2017-06-03

A simple form that I used to receive feedback from people on a web page. The web app uses JavaScript and only works on current browsers. I receive feedback if JavaScript is executed in the user's browser and the UserAgent of the browser (browser and operating system name and version).

This snippet only needs one file to both display the form and to receive the information.
Also needed is a configured mail server to send this information to me and the user (if she wishes it).

Important bits:

If POST data was received together with the request, get the data and send a mail. If not, display the feedback form to the user.

if ($_POST) {
  ... // get the transferred data and send a mail
} else {
  ... // write an HTML form
}

The POST data is read and sanitized with filter_input_array from the PHP filter extension. If a filter is not given for a key, FILTER_UNSAFE_RAW is used as default.

$filters = array(
  'comment' => FILTER_SANITIZE_FULL_SPECIAL_CHARS,
  'email' => FILTER_SANITIZE_EMAIL,
  'browser' => FILTER_UNSAFE_RAW,
  'os' => FILTER_UNSAFE_RAW,
  'js' => FILTER_UNSAFE_RAW
);
$arguments = filter_input_array(INPUT_POST, $filters);

To receive information about the browser and operating system of the user, I read the transmitted UserAgent information (even though it can be easily spoofed) with filter_input.

$useragent = filter_input(INPUT_SERVER, 'HTTP_USER_AGENT', FILTER_UNSAFE_RAW);

I set the form action to the current php file, this will work wherever this file is placed. No need to know about the url.

<form action="<?php echo $self; ?>" method="POST">

Because most users don't know about JavaScript, I added a hidden input element that is set to false. If JavaScript is executed, this value is set to true.

  <input type="hidden" name="js" value="false"/>
</form>

<script>
  document.forms[0].js.value = "true";
</script>

 

Full code

(feedback.php)

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Feedback form</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <style>
        body { font-family: sans-serif; }
        form label b { display: block; }
        form { max-width: 500px; }
        form textarea { width: 100%; }
    </style>
</head>
<body>

<?php
if ($_POST) {
    function withDefault($value) {
        $temp = (isset($value) && !empty($value)) ? $value : 'No input given';
        return "'$temp'";
    }

    $arguments = filter_input_array(INPUT_POST);
    $useragent = filter_input(INPUT_SERVER, 'HTTP_USER_AGENT');
    $send_copy = isset($arguments['receiveCopy']);

    $dev_mail = MY_MAIL;
    $subject = 'Feedback';
    $from = "From: Own feedback <feedback@example.com>";
    $mail_body = withDefault($arguments['comment']) .
        "\n\n-----------\nAdditional information:\n" .
        'Email: ' . withDefault($arguments['email']) . "\n" .
        'Browser: ' . withDefault($arguments['browser']) . "\n" .
        'OS: ' . withDefault($arguments['os']) . "\n" .
        'Javascript active: ' . withDefault($arguments['js']) . "\n" .
        'Useragent: ' . $useragent . "\n" .
        'Time: ' . date('c') . "\n";


    // Might need configuration, see http://php.net/mail
    // Alternatives to using the built-in mail()
    //  * https://github.com/PHPMailer/PHPMailer
    //  * http://swiftmailer.org
    mail($dev_mail, $subject, $mail_body, $from);

    if ($send_copy && !empty($arguments['email'])) {
        mail($arguments['email'], $subject, $mail_body, $from);
    }

    echo '<h1>Feedback and additional data</h1>';
    echo "<pre><code>$mail_body</code></pre>";

} else {
    // display the feedback form
    $self = filter_input(INPUT_SERVER, 'PHP_SELF'); // full path of the current script
?>
    <h1>Feedback or bug report</h1>
    <p>In case of a bug, please describe the problem and also your steps that lead to the unexpected behavior.</p>
    <p>Each entry field is optional, but the more information is given, the better I can react to the feedback.</p>
    <p>The E-mail address is not saved on the server. It is only used to send you a copy of your feedback and to allow me to contact you for additional information.</p>

    <noscript>
        <h2>Important information</h2>
        <p>This website uses JavaScript for interactive behavior. <br>At the moment, executing Javascript is <b>not allowed</b>, this might be a reason for unexpected behavior.</p>
    </noscript>

    <form action="<?php echo $self; ?>" method="POST">
        <label>
            <b>Your E-mail address</b>
            <input type="email" name="email" />
            <label><input type="checkbox" name="receiveCopy" value="receiveCopy" checked="checked"/>send me a copy</label>
        </label>
        <label>
            <b>Description</b>
            <textarea name="comment" rows="10"></textarea>
        </label>
        <hr />
        <label>
            <b>Browser (including version)</b>
            <input type="text" name="browser" placeholder="E.g. Internet Explorer 8" />
        </label>
        <label>
            <b>Operating system (including version)</b>
            <input type="text" name="os" placeholder="E.g. Windows 7"/>
        </label>

        <input type="hidden" name="js" value="false"/>
        <hr />

        <input type="submit" value="send feedback" />
    </form>

    <script>
        document.forms[0].js.value = "true";
    </script>
<?php
}
?>

</body>
</html>