POST/REDIRECT/GET not working in PHP contact form - php

I am trying to configure a basic contact POST form with one checkbox input and server-side validation. This means the form must submit to itself, so a self-serving contact form. The problem I'm having is when refreshing the page, the form is submitted again.
I am using session data to store form validation as this form is an initial popup to which the user must tick and confirm to enter the page. The page has two contact forms on it but I am showing one and I think the implementation should be the same for both (correct me if I'm wrong). Once the user ticks the box and submits the form, the popup form will hide allowing the user to see the page.
To solve this, I believe the POST/REDIRECT/GET design pattern should prevent this, however, I don't think my implementation is correct and I don't know what is wrong in my code.
index.php code below:
<!DOCTYPE html>
<html lang="en">
<?php
session_start();
include('form_process.php');
?>
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="assets/css/main.min.css" />
</head>
<body>
<section id="selfCertOverlay" <?=$_SESSION['closeSelfCert']?>>
<div class="blurOverlay">
<form id="selfCert" method="post">
<label for="self_cert">I have read and confirm the statement.
<input type="checkbox" name="self_cert" id="self_cert">
<span id="checkmark" class="<?= ($_SESSION['self_cert_checkbox_error']) ? 'inputError' : ''; ?>"></span>
<span class="error"><?= (isset($_SESSION["self_cert_error"])) ? $_SESSION["self_cert_error"] : ''; ?></span>
</label>
<input type="submit" name="submit_self_cert" value="Confirm & Proceed">
</form>
</div>
</section>
</body>
</html>
form_process.php code below:
<?php
$_SESSION["self_cert_error"] = "";
$_SESSION["self_cert_checkbox_error"] = false;
if (!isset($_POST["self_cert"])) {
$_SESSION["self_cert_error"] = "Please read and accept the statement to proceed";
$_SESSION["self_cert_checkbox_error"] = true;
} else {
unset($_SESSION["self_cert_error"]);
$message_body = '';
unset($_POST['submit']);
foreach ($_POST as $key => $value) {
$keyOutput = str_replace('_', ' ', $key);
$keyOutput = ucwords($keyOutput);
$message_body .= "$keyOutput: $value\n";
}
$to = 'example#mailprovider.com';
$subject = 'Email Subject';
if (mail($to, $subject, $message_body)){
$_SESSION["closeSelfCert"] = 'style="display: none;"';
// Redirect to itself.
header( "Location: {$_SERVER['REQUEST_URI']}", true, 303 );
return;
}
}
?>

The refresh button on the browser resends the last HTTP request that was sent by the client. This is why when you refresh the page, it re-submits the form.
The only way to get around this is to use the POST/REDIRECT method.
To setup a POST/REDIRECT method, use an intermediate page to do the operations and then redirect to the original form afterwards.
For example:
index.php --> the page with the form on - make sure the form has action="form_process.php" declared, so it will POST the data to the form_process.php script
form_process.php --> receives the form data and carries out your operations, then redirects back to the index.php page at the end.
So your final code should look something like the below;
index.php
I have removed the include('form_process.php'); at the top
I have added action="form_process.php" to the <form> tag
<!DOCTYPE html>
<html lang="en">
<?php
session_start();
?>
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="assets/css/main.min.css" />
</head>
<body>
<section id="selfCertOverlay" <?=$_SESSION['closeSelfCert']?>>
<div class="blurOverlay">
<form id="selfCert" method="post" action="form_process.php">
<label for="self_cert">I have read and confirm the statement.
<input type="checkbox" name="self_cert" id="self_cert">
<span id="checkmark" class="<?= ($_SESSION['self_cert_checkbox_error']) ? 'inputError' : ''; ?>"></span>
<span class="error"><?= (isset($_SESSION["self_cert_error"])) ? $_SESSION["self_cert_error"] : ''; ?></span>
</label>
<input type="submit" name="submit_self_cert" value="Confirm & Proceed">
</form>
</div>
</section>
</body>
</html>
form_process.php
I have added session_start(); at the top so you can access the $_SESSION data
I have added header( "Location: index.php", true, 303 ); within your first IF statement
I have altered your header() routing which takes place after you send your email, so this redirects back to index.php
<?php
session_start();
$_SESSION["self_cert_error"] = "";
$_SESSION["self_cert_checkbox_error"] = false;
if (!isset($_POST["self_cert"])) {
$_SESSION["self_cert_error"] = "Please read and accept the statement to proceed";
$_SESSION["self_cert_checkbox_error"] = true;
header( "Location: index.php", true, 303 );
exit;
} else {
unset($_SESSION["self_cert_error"]);
$message_body = '';
unset($_POST['submit']);
foreach ($_POST as $key => $value) {
$keyOutput = str_replace('_', ' ', $key);
$keyOutput = ucwords($keyOutput);
$message_body .= "$keyOutput: $value\n";
}
$to = 'example#mailprovider.com';
$subject = 'Email Subject';
if (mail($to, $subject, $message_body)){
$_SESSION["closeSelfCert"] = 'style="display: none;"';
// Redirect back to the form page.
header( "Location: index.php", true, 303 );
exit;
}
}
?>

Related

PHP problems with linking HTML. Doesn't redirect

Basically my shirt e-commerce website won't redirect to my html website. Whenever I try to click on the virtual try on button next to the shirt, it doesn't redirect me to the page instead it just loads and refreshes the current page. Any tips?
Here is my code:
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="get">
<input type="hidden" name="product_id" value="124">
<input type="submit" value="Virtual Try ON" name="form_virtual_try_on">
</form>
<?php
$product_id = $_GET['product_id'] ?? '';
switch ($product_id) {
case '124':
$text = 'Virtual Try On';
$link = 'vton_ls.html';
break;
default:
$text = '';
$link = '';
break;
}
if (isset($_GET['form_virtual_try_on'])) {
$product_id = $_GET['product_id'];
if ($product_id == '124') {
header('Location: vton_ls.html');
exit;
} else {
echo "Invalid product ID";
}
}
?>
<div class="share">
<?php echo LANG_VALUE_58; ?> <br>
<div class="sharethis-inline-share-buttons"></div>
</div>
I tried GET, switch case, and redoing all my codes from scratch but it doesn't seem to work.
By simply adding little snippets of code rather than the actual full page it is potentially easy to misinterpret what you are trying to do and why things are going awry so if the following is not correct I apologise.
Given a testing target page (vton_ls.html) and an interpretation of the above
<?php
session_start();
if( !defined('LANG_VALUE_58') )define('LANG_VALUE_58','LANG_VALUE_58......... ok');
if( $_SERVER['REQUEST_METHOD']=='GET' && isset( $_GET['product_id'] ) ){
switch( intval( $_GET['product_id'] ) ){
case 124:
$text = 'Virtual Try On';
$link = 'vton_ls.html';
break;
default:
$text = '';
$link = '';
break;
}
exit( header( sprintf('Location: %s?product_id=%s&text=%s', $link, $_GET['product_id'], $text ) ) );
}
?>
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title></title>
</head>
<body>
<form method='get'>
<input type='hidden' name='product_id' value='124' />
<input type='submit' />
</form>
<div class='share'>
<?php echo LANG_VALUE_58; ?> <br>
<div class='sharethis-inline-share-buttons'></div>
</div>
</body>
</html>
By clicking the button the form submits to the same page where the GET request is processed to build the new url that redirects to your html website
You already added the header and pls add anchor tag too
header ('Location: vton_ls.html');
you're trying to link from an HTML page to a PHP page, you can use an anchor tag like this:
Virtual Try-On
If you fail to complete this, you’ll probably see an error message that tells you “headers are already sent.” The error might not be a massive one — the header function is so finicky that a single white space can prompt this error.
<?php
header('Location: http://www.example.com/');
exit;
?>
<head>
<title>Example</title>
</head>
<body>
<p>Hello, world!</p>
</body>

How do fix '404 page not found' error when running a php file?

I am just starting to learn php and when I run my php file, no matter the browser, i get a 404 error. What is my code missing that is causing this? This file is supposed to display a message after a user submits a 'contact me' form.
<!DOCTYPE html>
<html lang="">
<head>
<title>Contact Form Submitted</title>
</head>
<body>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST">
<p>
Thank you, <?php echo $_POST["name"]; ?> for your comments<br>
You stated in your test Message:<br>
<?php echo $_POST["message"]; ?>
We will respond to you at <?php echo $_POST["email"]; ?> when we make updates to the site.
</p>
</body>
</html>
this code works. see this is firefox: https://i.imgur.com/YeBFt9B.png
<?php
// var // variable value // default value
$php_path = $_SERVER['PHP_SELF'] ?? "";
$name = $_POST["name"] ?? "name";
$message = $_POST["message"] ?? "message";
$email = $_POST["email"] ?? "email";
?>
<!DOCTYPE html>
<html lang="">
<head>
<title>Contact Form Submitted</title>
</head>
<body>
<form action="<?= $php_path ?>" method="POST">
<p>
Thank you, <?= $name ?> for your comments<br>
You stated in your test Message:<br>
<?= $message ?>
<br><br>
We will respond to you at <?= $email ?> when we make updates to the site.
</p>
</form>
</body>
</html>
if you don't specify a default value on your parameters from another form you could run into an unexpected error. This version is better ;)
I'm sure you get this error because you have a typo in one of your urls
First of all use htmlspecialchars in:
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
you prevent XSS attack if user enter url like: http://www.example.com/test_form.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E
If you are getting 404 error it's probably becouse your action of the form on contact me page don't point to right script.
If you have two separate files, one for form and second for thanks message you have to make sure than the urls are correct.
// form.php
...
<form action="thanks-message.php">
...
</form>
...
// thanks-message.php
<?php
$name = $_POST["name"] ?? "Joe";
$message = $_POST["message"] ?? "Lorem ipsum...";
$email = $_POST["email"] ?? "joe#example.com";
?>
...
<p>
Thank you, <?= $name ?> for your comments<br>
You stated in your test Message:<br>
<?= $message ?>
<br><br>
We will respond to you at <?= $email ?> when we make updates to the site.
</p>
...
form element is not necessary on this page

Need Assistance With a Simple HTML/PHP Web Page

I'm trying to write a simple PHP web page that asks the user to input a domain and then click the SUBMIT button. When the user clicks SUBMIT the page should display the name of the domain that they typed in.
I have XAMPP installed on my computer and I have a file named test234.php in my htdocs directory. This PHP file contains the following PHP and HTML code:
<?php
$message = "";
if (!isset($domain)) {
$message = "<br>Enter a domain<br>";
} else {
$message = "You typed in $domain as the domain";
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Some title</title>
</head>
<body>
<h1 align="center">
Some title
<?php print $message ?>
</h1>
<form method="POST" align="center">
Domain: <input type="text" name="domain"><input type="submit" align="center"><br>
</form>
</body>
</html>
When I type in a domain and click SUBMIT it just reloads the same page asking for the user to type in a domain. I want it to output the text "You have typed in $domain as the domain" but can't seem to get it to work. Any help would be appreciated.
The value of $domain was never declared. If you would like to get form data you need to use the $_GET, $_POST, or $_REQUEST object(s), in your case you are using the post method in your form so instead of $domain use $_POST["domain"]:
<?php
$message = "";
$domain = $_POST["domain"];
if (!isset($domain)) {
$message = "<br>Enter a domain<br>";
} else {
$message = "You typed in $domain as the domain";
}
?>

PHP form not processing in process.php

I'm having difficulty figuring out why my PHP form is processing on process.php but not returning to the form page with the appropriate $messages. Am I missing a line of code? I wrote this all up myself and it's the first time.
Here is my html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Test Contact Form - jQuery</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="http://malsup.github.com/jquery.form.js"></script>
<script type="text/javascript" src="js/main.js"></script>
</head>
<body>
<h3>Contact Us</h3>
<?php echo $contact_message; ?>
<form id="myForm" method="post" action="process.php">
<input name="name" type="text" value="<?php echo $_POST[name]; ?>" placeholder="Name" required/>
<br>
<input name="email" type="email" value="<?php echo $_POST[email]; ?>" placeholder="you#yourmail.com" required/>
<br>
<textarea name="message" class="message" placeholder="We can answer your questions." required>
<?php echo $_POST[message]; ?>
</textarea>
<br>
<button type="submit" name="submit" class="btn send">
<img src="img/send.png">
</button>
<br>
<?php echo $contact_success_message; ?>
</form>
<!--close contact form-->
</body>
</html>
And here is my process.php
<?php
//checks for valid email
function is_valid_email($email) {
$result = true;
$pattern = '/^([a-z0-9])(([-a-z0-9._])*([a-z0-9]))*\#([a-z0-9])(([a-z0-9-])*([a-z0-9]))+(\.([a-z0-9])([-a-z0-9_-])?([a-z0-9])+)+$/i';
if(!preg_match($pattern, $email)) {
$result = false;
}
return $result;
}
//when send is pressed, validate fields
if(isset($_POST['submit'])) {
$valid = true;
$contact_message = '';
if ( $_POST['name'] == "" ) {
$contact_message .= "You forgot to tell us your name. ";
$valid = false;
}
if ( !is_valid_email($_POST['email']) ) {
$contact_message .= "A valid email is required, don't worry we don't share it with anyone. ";
$valid = false;
}
if ( $_POST['message'] == "" ) {
$contact_message .= "What did you want to ask us? ";
$valid = false;
}
//if everything checks out, send the message!
if ( $valid == true ) {
$safe_email = str_replace("\r\n","",$_POST[email]);
$mail = "From: $_POST[name]\n";
$mail .= "Email: $_POST[email]\n";
$mail .= "$_POST[message]\n";
mail('ME#MYEMAIL.COM','New Contact from RN+',$mail,"From: $safe_email\r\n");
$contact_success_message = 'Brilliant I say! We will be in contact with you shortly.';
//clear form when submission is successful
unset($_POST);
}
}
?>
I could have sworn that I've used this before but this time it's not returning to the contact page.
It looks like you meant to use the code like this:
form.php
<?php include 'process.php'; ?>
<!DOCTYPE html>
<html lang="en">
<head>
<title>Test Contact Form - jQuery</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="http://malsup.github.com/jquery.form.js"></script>
<script type="text/javascript" src="js/main.js"></script>
</head>
<body>
<h3>Contact Us</h3>
<?php echo $contact_message; ?>
<form id="myForm" method="post" action="process.php">
<input name="name" type="text" value="<?php echo $_POST[name]; ?>" placeholder="Name" required/><br>
<input name="email" type="email" value="<?php echo $_POST[email]; ?>" placeholder="you#yourmail.com" required/><br>
<textarea name="message" class="message" placeholder="We can answer your questions." required><?php echo $_POST[message]; ?></textarea><br>
<button type="submit" name="submit" class="btn send"><img src="img/se
__
formnd.png"></button><br>
<?php echo $contact_success_message; ?>
</form><!--close contact form-->
</body>
</html>
The form processor will set the appropriate variables you are outputting in your HTML code. Since process.php checks if the method is POST, you don't have to do that in the form page.
If you want process.php to redirect back to your form, you need to add a PHP header code like: header('Location: http://www.example.com/form.php');
If you want to carry through any data back to the original page, include it in the URL as a GET variable: header('Location: http://www.example.com/form.php?message='.$messagetext); You can then retrieve this on your form page through use of GET: echo $contact_success_message = $_GET['message'];
Do not forget to exit(); or die(); after your redirect!
If you don't have any reason for excluding a single PHP page, you could merge the two (form and process) into one php page.
<?php
//checks for valid email function
...
if(isset($_POST['submit'])) {
...
}
?>
...your HTML goes here...
This will display just the form if no data has been submitted, and if the form has been submitted will "reload" the page, perform the action, and display the appropriate message. Change the form action to action="" so the file will post to itself.
I would recommend using jQuery validation. It is easier and will help with any issues you might have in returning the message.
http://docs.jquery.com/Plugins/Validation
Something like this...
$("#myForm").validate({
rules: {
name: { required: true; }
},
messages: {
name: "You forgot to tell us your name.",
}
});
You can do this for email fields and for your whole form. You can find plenty of examples online.
Just include your other fields. If you do it this way the validation is client side and the form will process and then you forward to a thank you for contacting us page.

php contact form clean code

Trying to make my own contact form with php. Is there a better/cleaner way to approach this?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1 /DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Contact Form Practice</title>
</head>
<body>
<form method="POST" action="mailer.php">
Name:
<br>
<input type="text" name="name" size="19"><br>
<br>
Your Email Adress:
<br>
<input type="text" name="email" size="19"><br>
<br>
Message:
<br>
<textarea rows="9" name="message" cols="30"></textarea>
<br>
<br>
<input type="submit" value="Submit" name="submit">
</form>
</body>
</html>
----------------php---------------
<?php
if(isset($_POST['submit'])) {
$to = "mail#cheapramen.com";
$subject = "Contact";
$name_field = $_POST['name'];
$email_field = $_POST['email'];
$message = $_POST['message'];
$body = "From: $name_field\n E-Mail: $email_field\n Message:\n $message";
echo "Data has been submitted to $to!";
mail($to, $subject, $body);
} else {
echo "4! OH! 4!";
}
?>
The code seems correct, but I'd highly recommend adding in some data validation. You'll want to make sure all required fields are filled out with valid info. Also be sure to encode/strip any HTML, JS, etc for security/readability purposes.
Lastly, you should also consider using CAPTCHA to guard against spam. I've got an old site running code similar to this and used to get over 500 spam emails a day!
That's pretty much it, maybe on successful completion you can do a header() redirect to a confirmation page, but as far as processing the form what you have is pretty standard.
Also, you want to sanitize your data as a standard practice of accepting any user input.
You might want to look into implementing a CAPTCHA to prevent the bots from hammering your form as well.
PHP Captcha
One thing you definitely want to do is make the data a bit safer to send in the email. I would at least run the htmlentities and strip_tags on the input data but you should definitely look in to doing further validation.
Also instead of isset($_POST["SUBMIT"]) I would maybe do something like...
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// body code here
}
I would HIGHLY recommend looking up some information about PHP mail() hijacking and making sure you are not going to leave your script vulnerable to such an attack. Also what everyone else suggested is very good to do as well.
In the question, you had 2 separate files processing the form. The problem is if you get a validation error, you are left with little choice but the awful "Please click you back button" solution.
Consider this template PHP file that will handle it all on one page, provide for data validation, errors, re-submitting, and the whole 9 yards.
<?php
// Read input variables from _POST
$FormAction = (isset($_POST['FormAction']) ? $_POST['FormAction'] : '');
$FirstName = trim(isset($_POST['FirstName']) ? $_POST['FirstName'] : '');
...
// Define script variables
$Errors = array();
// Process input if data was posted.
switch($FormAction)
{
case 'Process':
// validation code
if(empty($FirstName) or strlen($FirstName) > 20)
$Errors[] = "First name is required.";
...
if(count($Errors) > 0)
break;
// Here we have valid data.. Do whatever...
// Now, redirect somewhere.
header('Location: http://www.next.com/whatever');
exit;
}
?>
<html>
<body>
<?php if(count($Errors)) { ?>
<div class="Error">
<?php foreach($Error as $Error) { ?>
<div><?php echo htmlspecialchars($Error); ?></div>
<?php } ?>
</div>
<?php } ?>
<form method="POST" action="<?php echo htmlspecialchars($_SERVER['REQUES_URI'], ENT_QUOTES); ?>" />
<input type="hidden" name="FormAction" value="Process" />
First Name:
<input type="text" name="FirstName" value="<?php echo htmlspecialchars($FirstName, ENT_QUOTES); ?>" />
...
<input type="submit" />
</form>
</body>
</html>

Categories