25

I have made a contact form based on this tutorial: http://blog.teamtreehouse.com/create-ajax-contact-form

I'm using PHP Version 5.3.10-1ubuntu3.4 on my server and I've been having trouble with http_response_code(); which is what the example tutorial at the above link uses. I've read http_response_code(); only works with PHP 5.4. So instead I have reverted to using header();.

I have my form working just fine and it's displaying a success message when I submit, rather than errors when I was using http_response_code(); but my PHP isn't that great and I am wanting to know if what I have done is acceptable or if I should be doing it a different way? Please correct my code if so.

Here's the contents of my mailer.php file, where you can see I've commented out http_response_code(); and am using header();.

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // Get the form fields and remove whitespace.
    $name = strip_tags(trim($_POST["name"]));
    $name = str_replace(array("\r","\n"),array(" "," "),$name);
    $email = filter_var(trim($_POST["email"]), FILTER_SANITIZE_EMAIL);
    $phone = trim($_POST["phone"]);
    $company = trim($_POST["company"]);
    $minbudget = trim($_POST["minbudget"]);
    $maxbudget = trim($_POST["maxbudget"]);
    $message = trim($_POST["message"]);
    $deadline = trim($_POST["deadline"]);
    $referred = trim($_POST["referred"]);

    // Check that data was sent to the mailer.
    if ( empty($name) OR empty($phone) OR empty($message) OR !filter_var($email, FILTER_VALIDATE_EMAIL)) {
        // Set a 400 (bad request) response code and exit.
        //http_response_code(400);
        header("HTTP/1.1 400 Bad Request");
        echo "Error (400). That's not good, refresh and try again otherwise please email me and let me know you are having trouble submitting this form.";
        exit;
    }

    // Set the recipient email address.
    // FIXME: Update this to your desired email address.
    $recipient = "[email protected]";

    // Set the email subject.
    $subject = "Website enquiry from $name";

    // Build the email content.
    $email_content = "Name: $name\n";
    $email_content .= "Email: $email\n\n";
    $email_content .= "Phone: $phone\n";
    $email_content .= "Company: $company\n\n";

    $email_content .= "Budget: $minbudget $maxbudget\n";
    $email_content .= "Deadline: $deadline\n";
    //$email_content .= "Max Budget: $maxbudget\n";

    $email_content .= "\n$message\n\n";        

    $email_content .= "Referred: $referred\n";

    // Build the email headers.
    $email_headers = "From: $name <$email>";

    // Send the email.
    if (mail($recipient, $subject, $email_content, $email_headers)) {
        // Set a 200 (okay) response code.
        //http_response_code(200);
        header("HTTP/1.1 200 OK");
        echo "Thank You! I'll be in touch soon.";
    } else {
        // Set a 500 (internal server error) response code.
        //http_response_code(500);
        header("HTTP/1.0 500 Internal Server Error");
        echo "Error (500). That's not good, refresh and try again otherwise please email me and let me know you are having trouble submitting this form.";
    }

} else {
    // Not a POST request, set a 403 (forbidden) response code.
    //http_response_code(403);
    header("HTTP/1.1 403 Forbidden");
    echo "Error (403). That's not good, refresh and try again otherwise please email me and let me know you are having trouble submitting this form.";
}
3
  • 3
    Please don't change the HTTP status codes unless you're actually using them correctly, 403 is being missused(it's supposed to indicate that you lack permission, not that you're submitting the request wrong, that's what 405 is for), and you shouldn't be submitting 400 errors unless the headers are actually corrupt(since 400 indicates an error parsing the headers, which there clearly isn't). Commented Aug 14, 2014 at 11:09
  • 1
    Your mail code has many problems - I suggest you use a library, such as PHPMailer, since you tagged the question with that, but are not using it! Commented Aug 14, 2014 at 11:45
  • 1
    @scragar - not true. Using 400's as a response to malformed/invalid data in json/api post, is fairly common place, and is further supported by this popular thread on stackoverflow Commented Dec 22, 2016 at 22:15

3 Answers 3

33

I've managed to answer this on my own similar question by going through the PHP source code to work out exactly what happens.

The two methods are essentially functionally equivalent. http_response_code is basically a shorthand way of writing a http status header, with the added bonus that PHP will work out a suitable Reason Phrase to provide by matching your response code to one of the values in an enumeration it maintains within php-src/main/http_status_codes.h.

Note that this means your response code must match a response code that PHP knows about. You can't create your own response codes using this method, however you can using the header method. Note also that http_response_code is only available in PHP 5.4.0 and higher.

In summary - The differences between http_response_code and header for setting response codes:

  1. Using http_response_code will cause PHP to match and apply a Reason Phrase from a list of Reason Phrases that are hard-coded into the PHP source code.

  2. Because of point 1 above, if you use http_response_code you must set a code that PHP knows about. You can't set your own custom code, however you can set a custom code (and Reason Phrase) if you use the header function.

  3. http_response_code is only available in PHP 5.4.0 and higher

Sign up to request clarification or add additional context in comments.

3 Comments

If http_response_code(403); is used somewhere in a script, should it be followed by exit? Or does further execution get terminated implicitly by http_response_code(403);?
It doesn't terminate execution. So if you want to exit after setting the response code you'll have to explicitly exit.
@W.M. just imagine a 404 error page - you want to first set up the correct HTTP response, but then still show an error message using normal HTML code. Also this response should be accepted as the right one.
7

Easy solution:

/**
 * Sets the response code and reason
 *
 * @param int    $code
 * @param string $reason
 */
function setResponseCode($code, $reason = null) {
    $code = intval($code);

    if (version_compare(phpversion(), '5.4', '>') && is_null($reason))
        http_response_code($code);
    else
        header(trim("HTTP/1.0 $code $reason"));

}

you can use it as:

setResponseCode(404);

or

setResponseCode(401,'Get back to the shadow');

1 Comment

Nice little wrapper method! In production, that else should already grab from a list of $reason values either hard-coded or from a language file with constants.
2

To answer your main question, the biggest response I could see to using headers vs http_response_code(), is that http_response_code() is only supported on PHP 5.4 and greater, older versions would fail using that function.

Using headers as you are in your example will insure you're code will work on older versions.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.