Jump to content
Larry Ullman's Book Forums

Recommended Posts

I am working with the "secure" version of contact form script 12.1 described in "Chapter 12 - Security Methods" (pg. 365) but would like to modify this so that rather than simply printing a thank you message, the user is redirected to a thank you page.

 

I have tried replacing the given script:

// Minimal form validation:
    if (!empty($scrubbed['email'])) {
    
        // Create the body:
        $body = "Name: {$scrubbed['name']}\n\nComments: {$scrubbed['comments']}";
        $body = wordwrap($body, 70);
    
        // Send the email:
        mail('XXX@XXX', 'Contact Form Submission', $body, "From: {$scrubbed['email']}");
        
        // Print a message:
        echo '<p><em>Thank you for contacting me. I will reply some day.</em></p>';
        
        // Clear $_POST (so that the form's not sticky):
        $_POST = array();
    
    } else {
        echo '<p style="font-weight: bold; color: #C00">Please enter a valid email address.</p>';
    }

with modified:

 // Minimal form validation:
    if (!empty($scrubbed['email'])) {
    
        // Create the body:
        $body = "Name: {$scrubbed['name']}\n\nComments: {$scrubbed['comments']}";
        $body = wordwrap($body, 70);
    
        // Send the email:
        mail('XXX@XXX', 'Contact Form Submission', $body, "From: {$scrubbed['email']}");
        
          // Redirect to thank you page:
        header("Location: thankyou.htm");
        exit();
        
        
        // Clear $_POST (so that the form's not sticky):
        $_POST = array();
    
    } else {
        echo '<p style="font-weight: bold; color: #C00">Please enter a valid email address.</p>';
    }

..but get the error:

 

Warning: Cannot modify header information - headers already sent by (output started at /websites.....

 

Reading about this, it seems nothing can be sent to the browser before header is used. But however I try to move things around, I cannot get this to work.

 

Could you advise how/where this redirect should be used within this script? Thank you.

Link to comment
Share on other sites

You must be outputting something before trying to redirect. Do you include any files that could cause the issue or anything similar? I guarantee you this is the problem, so keep looking. Take specifically notice of the file and line number the error message is referring to and start looking from there.

 

Good luck.

Link to comment
Share on other sites

Hi Antonio, thank you for your message.

 

At the moment I'm using exactly the test script 12.1 from the book, but simply replacing:

echo '<p><em>Thank you for contacting me. I will reply some day.</em></p>';

with

header("Location: thankyou.htm");

[not sure if I also need exit(); afterwards but this doesn't seem to help]

 

The error gives line 53, which is the line containing

header("Location: thankyou.htm");

---

So the entire page code is:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
    <title>Contact Me</title>
</head>
<body>
<h1>Contact Me</h1>
<?php # Script 12.1 - email.php #2

// Check for form submission:
if (isset($_POST['submitted'])) {

    /* The function takes one argument: a string.
    * The function returns a clean version of the string.
    * The clean version may be either an empty string or
    * just the removal of all newline characters.
    */
    function spam_scrubber($value) {
    
        // List of very bad values:
        $very_bad = array('to:', 'cc:', 'bcc:', 'content-type:', 'mime-version:', 'multipart-mixed:', 'content-transfer-encoding:');
        
        // If any of the very bad strings are in
        // the submitted value, return an empty string:
        foreach ($very_bad as $v) {
            if (stripos($value, $v) !== false) return '';
        }
        
        // Replace any newline characters with spaces:
        $value = str_replace(array( "\r", "\n", "%0a", "%0d"), ' ', $value);
        
        // Return the value:
        return trim($value);
    
    } // End of spam_scrubber() function.
    
    // Clean the form data:
    $scrubbed = array_map('spam_scrubber', $_POST);

    // Minimal form validation:
    if (!empty($scrubbed['name']) && !empty($scrubbed['email']) && !empty($scrubbed['comments']) ) {
    
        // Create the body:
        $body = "Name: {$scrubbed['name']}\n\nComments: {$scrubbed['comments']}";
        $body = wordwrap($body, 70);
    
        // Send the email:
        mail('example@example.com', 'Contact Form Submission', $body, "From: {$scrubbed['email']}");
        
        // Print a message:
        header("Location: thankyou.htm");
        
        // Clear $_POST (so that the form's not sticky):
        $_POST = array();
    
    } else {
        echo '<p style="font-weight: bold; color: #C00">Please fill out the form completely.</p>';
    }
    
} // End of main isset() IF.
?>
<p>Please fill out this form to contact me.</p>
<form action="test-email-fresh.php" method="post">
    <p>Name: <input type="text" name="name" size="30" maxlength="60" value="<?php if (isset($_POST['name'])) echo $_POST['name']; ?>" /></p>
    <p>Email Address: <input type="text" name="email" size="30" maxlength="80" value="<?php if (isset($_POST['email'])) echo $_POST['email']; ?>" /></p>
    <p>Comments: <textarea name="comments" rows="5" cols="30"><?php if (isset($_POST['comments'])) echo $_POST['comments']; ?></textarea></p>
    <p><input type="submit" name="submit" value="Send!" /></p>
    <input type="hidden" name="submitted" value="TRUE" />
</form>
</body>
</html>

---

 

Am I doing something silly?

Link to comment
Share on other sites

Bob, it would help us a lot if your code were better formatted.

Could you please go back and edit both of your posts by highlighting the code, and then clicking the "<>" button to put all the code within code tags?

 

Thank you.

 

Thanks for the pointer - I've done that now.

 

You are outputting HTML to the browser before you run the PHP. That's your problem here.

 

Assign things to variables instead of echoing the out directly, and echo the variables inside your HTML instead. Also move any HTML below the PHP logic.

 

Thank you - I see how that there's the <h1> before the php runs - I assume that's the issue then. I'll see if I can reorder things!

Link to comment
Share on other sites

You can't have ANY ouput to the browser before a redirect, not even a doctype or other non-viewable elements. Take a look at how Larry generally structure his scripts. In this specific case, this should work out for you:

<?php # Script 12.1 - email.php #2

/* The function takes one argument: a string.
 * The function returns a clean version of the string.
 * The clean version may be either an empty string or
 * just the removal of all newline characters.
 */
function spam_scrubber($value) {

    // List of very bad values:
    $very_bad = array('to:', 'cc:', 'bcc:', 'content-type:', 'mime-version:', 'multipart-mixed:', 'content-transfer-encoding:');

    // If any of the very bad strings are in
    // the submitted value, return an empty string:
    foreach ($very_bad as $v) {
        if (stripos($value, $v) !== false) return '';
    }

    // Replace any newline characters with spaces:
    $value = str_replace(array( "\r", "\n", "%0a", "%0d"), ' ', $value);

    // Return the value:
    return trim($value);
    
} // End of spam_scrubber() function.

// Check for form submission:
if (isset($_POST['submitted'])) {
    
    // Clean the form data:
    $scrubbed = array_map('spam_scrubber', $_POST);

    // Minimal form validation:
    if (!empty($scrubbed['name']) && !empty($scrubbed['email']) && !empty($scrubbed['comments']) ) {
    
        // Create the body:
        $body = "Name: {$scrubbed['name']}\n\nComments: {$scrubbed['comments']}";
        $body = wordwrap($body, 70);
    
        // Send the email:
        mail('example@example.com', 'Contact Form Submission', $body, "From: {$scrubbed['email']}");
        
        // Print a message:
        header("Location: thankyou.htm");
        exit();
    
    } 
    else 
    {
        $message = 'Please fill out the form completely.';
    }
    
} // End of main isset() IF.
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
    <title>Contact Me</title>
</head>
<body>
<h1>Contact Me</h1> 
<p style="font-weight: bold; color: #C00"><?php if (isset($message)) echo $message; ?></p>
<p>Please fill out this form to contact me.</p>
<form action="test-email-fresh.php" method="post">
    <p>Name: <input type="text" name="name" size="30" maxlength="60" value="<?php if (isset($_POST['name'])) echo $_POST['name']; ?>" /></p>
    <p>Email Address: <input type="text" name="email" size="30" maxlength="80" value="<?php if (isset($_POST['email'])) echo $_POST['email']; ?>" /></p>
    <p>Comments: <textarea name="comments" rows="5" cols="30"><?php if (isset($_POST['comments'])) echo $_POST['comments']; ?></textarea></p>
    <p><input type="submit" name="submit" value="Send!" /></p>
    <input type="hidden" name="submitted" value="TRUE" />
</form>
</body>
</html>

Notice how I bind the output to $message instead of echoing it directly. Also see that all HTML is below the PHP. As PHP is executed top-to-bottom, that makes all the difference. Also, try not to mix HTML into your PHP code. Let styling be in you HTML. :)

  • Upvote 1
Link to comment
Share on other sites

 Share

×
×
  • Create New...