Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

PHP

Parvez Noor
PLUS
Parvez Noor
Courses Plus Student 15,917 Points

Need help creating a simple contact form.

Hi guys,

I'm making a simple website. It doesn't have too much functionality. The header and footer are included using php.

There is only one page - the index page.

On the index page, I have a simple contact form at the bottom. I've tried to connect this to my gmail using SMTP, after following Alena's building a basic PHP website course.

Everything seems to be working, except, it's not! I can still send the form without entering anything in the fields. Also, the page doesn't redirect to index.php?status=thanks. When I refresh the page, it still has problems with double form submission, and, worst of all, I'm still not getting any emails!

This is the website: http://tuwo.000webhostapp.com/

I'm assuming the whole if($_SERVER["REQUEST_METHOD"] == "POST") conditional is not even working, Can anyone help me figure out why?

Here is my code (I've removed most irrelevant html code to just show the form and the phpmailer code):

 <?php 
        use PHPMailer\PHPMailer\PHPMailer;
        use PHPMailer\PHPMailer\Exception;
        require 'vendor/phpmailer/src/PHPMailer.php';
        require 'vendor/phpmailer/src/Exception.php';
        require 'vendor/phpmailer/src/SMTP.php';

        if($_SERVER["REQUEST_METHOD"] == "POST") {
            $name = trim(filter_input(INPUT_POST,"name",FILTER_SANITIZE_STRING));
            $email = trim(filter_input(INPUT_POST,"email",FILTER_SANITIZE_EMAIL));
            $subject = trim(filter_input(INPUT_POST,"subject",FILTER_SANITIZE_STRING));
            $message = trim(filter_input(INPUT_POST,"message",FILTER_SANITIZE_SPECIAL_CHARS)); 

            if ($name == "" || $email == "" || $message == "") {
                $error_message = "Please fill in the required fields: Name, Email, Message";
                }
                if (!isset($error_message) && $_POST["address"] != "") {
                $error_message =  "Bad form input";
            }
            if (!isset($error_message) && !PHPMailer::validateAddress($email)) {
                $error_message =  "Invalid Email Address";
            }
            if(!isset($error_message)) {
                $email_body = "";
                $email_body .= "Contact by " . $name . " about " . $subject . "\n";
                $email_body .= "Message: " . $message . "\n";
                $email_body .= "Reply to " . $name . ": " . $email;

                $mail = new PHPMailer;
                try {
                    $mail->SMTPDebug = 2;
                    $mail->isSMTP();
                    $mail->Host = 'smtp.gmail.com';
                    $mail->Port = 587;
                    $mail->SMTPSecure = 'tls';
                    $mail->SMTPAuth = true;
                    $mail->Username = "email";
                    $mail->Password = "password";
                    $mail->setFrom('email', $name);
                    $mail->addReplyTo($email, $name);
                    $mail->addAddress('email', 'Parv Noor');
                    $mail->Subject = $subject . " from " . $name;
                    $mail->Body = $email_body;
                    if 
                        ($mail->send()) {
                        header("location:index.php?status=thanks");
                        exit;
                        } 
                } catch (Exception $e) { 
                    $error_message = "Mailer Error: " . $mail->ErrorInfo;
                }
            }
        }
        include("inc/header.php");
        ?>

          <section class="contact-us">
                <h1 class="get-in-touch">Get In Touch</h1>
                <?php if(isset($_GET["status"]) && $_GET["status"] == "thanks") {
                    echo  "<p> Thanks for the email! I&rsquo;ll check out your suggestion shortly!</p>"; 
                  } else { ?>
                <form class="contact-us-form" method="post" action="index.php">
                    <input class="name" type="text" id="name" name="name" placeholder="Name" value="<?php 
                    if (isset($name)) echo $name; ?>"/>
                    <input class="email" type="text" id="email" name="email" placeholder="Email" value="<?php 
                    if (isset($email)) echo $email;?>"/>
                    <input class="subject" type="text" id="subject" name="subject" placeholder="Subject" value="<?php 
                    if (isset($subject)) echo $subject;?>"/>
                    <textarea class="message" id="message" name="message" placeholder="Message"><?php 
                        if (isset($message)) echo htmlspecialchars($_POST['message']);
                        ?></textarea>
                    <input style="display:none" type="text" id="address" name="address" placeholder="Please leave blank" />
                    <input class="submit button" type="submit" value="Send">
                </form>
            </section>
            <?php } 
            include("inc/footer.php");
            ?>

5 Answers

Ah okk so headers already sent usually means you have echoed something before calling the header function.

The header function must be called before any actual output is sent, this includes HTML or PHP... for example this wouldn't work

<!doctype html>
<html>
<?php
header("location:index.php?status=thanks");

which line of code is 39?

Hard to really tell without php debug myself but can you check your filter is correct and see if its actually getting the request. setting the below should do to see if anything returns in the value. You will have to remove the rest of the or conditions, i just want to see if the error_message is the issue.

<?php
$name = isset( $_POST['name'] ) ? $_POST['name'] : 'something went wrong';

also, address is always === empty as it is hidden, without any value so it will never be set at this point in time

<?php

if (!isset($error_message) && $_POST["address"] != "")
Parvez Noor
PLUS
Parvez Noor
Courses Plus Student 15,917 Points

Hey,

Yes, it definitely has something to do with the error_message.

I am receiving emails now, however when I submit the form it refreshes index.php to, what looks like, a var_dump of all the information passed between the client and the server. At the bottom of all the text on the screen between the server and the client it says:

Warning: Cannot modify header information - headers already sent by (output started at /storage/ssd4/602/9749602/public_html/index.php:1) in /storage/ssd4/602/9749602/public_html/index.php on line 39

I think this is referring to the header redirect from:

<?php
if 
                        ($mail->send()) {
                        header("location:index.php?status=thanks");
                        exit;
                        } 

As the page redirects to index.php - so it is ignoring this code.

I adjusted the code to look like this:

<?php 
        use PHPMailer\PHPMailer\PHPMailer;
        use PHPMailer\PHPMailer\Exception;
        require 'vendor/phpmailer/src/PHPMailer.php';
        require 'vendor/phpmailer/src/Exception.php';
        require 'vendor/phpmailer/src/SMTP.php';

        if($_SERVER["REQUEST_METHOD"] == "POST") {
            $name = trim(filter_input(INPUT_POST,"name",FILTER_SANITIZE_STRING));
            $email = trim(filter_input(INPUT_POST,"email",FILTER_SANITIZE_EMAIL));
            $subject = trim(filter_input(INPUT_POST,"subject",FILTER_SANITIZE_STRING));
            $message = trim(filter_input(INPUT_POST,"message",FILTER_SANITIZE_SPECIAL_CHARS)); 

            $name = isset( $_POST['name'] ) ? $_POST['name'] : 'something went wrong';

            if(!isset($error_message)) {
                $email_body = "";
                $email_body .= "Contact by " . $name . " about " . $subject . "\n";
                $email_body .= "Message: " . $message . "\n";
                $email_body .= "Reply to " . $name . ": " . $email;

// below this is the same code

is that what you meant?

Now that we are aware that it's the error message causing the problem, is there anyway to fix this whilst still maintaining the safeguards?

Thanks so much for the help! I've been trying to fix this for daaaaays!!

Parvez Noor
PLUS
Parvez Noor
Courses Plus Student 15,917 Points

The code at line 39 was the code I posted with the header.

I just removed it, and the form sends an email now, without populating the page with messages between the server and the client. So all in all, the form is working and redirecting properly.

The only problem now is, as I try to reintroduce the error_messages and checks, they're just not registering at all.