I have a website where any visitor can subscribe to receive the newsletter.I encountered the problem of having my resubmitted when everytime when i refreshed the page.I solved it by applying the PRG concept. Now a user never submits the same form twice, i have just one problem : i have designed the form in such a way that when the is succesfully/or fails a message is display under the input fields. Unfortunatly now that i have the PRG concept applied i never get any message displayed . What to do ?
index.php - where i have the divs containing the submit form and the message display
<div id="newsletter" >
<form id="abonat" name="abonat" action="formular.php" method="post" onsubmit="return golire()" autocomplete="on" >
<span>Subscribe</span>
<input type="text" id="nume" name="nume" placeholder="Name" required />
<input type="email" id="email" name="email" placeholder="Email" autocomplete="off" required/>
<input type="submit" value="Subscribe" class="button" style="width:26%;float:left;" />
</form>
</div>
<div id="mesaj_newsletter">
<span><?php if (isset($mesaj)) echo $mesaj; ?> </span>
</div>
formular.php - where the validation takes place,and the message is decided
include('conect.php');
function validEmail($email){
//code that verifies if it is a valid email adress
}
if( (isset($_POST['email']))&&(isset($_POST['nume'])) ){
$nume=mysql_real_escape_string($_POST['nume']);
$email=mysql_real_escape_string($_POST['email']);
$z=1;
if(validEmail($email)==TRUE){
$result=mysql_query("SELECT * FROM abonat");
while($data=mysql_fetch_row($result)){
if(($data[1]==$email)||($data[2]==$nume))
$z=0;
}
if($z==1){
mysql_query("INSERT INTO abonat(email,nume) VALUES ('$email','$nume')");
$mesaj="Your email has been registered";
}
else $mesaj="You are already registered";
}
else $mesaj="You have not entered a valid email adress";
}
mysql_close($con);
header('Location:index.php');
?>
Try setting a cookie called e.g. $_COOKIE['status_message'] with 60 second timeout.
set_cookie('status_message','This is our message',(time()+60));
Then when the page is refreshed, check to see if the cookie has any data;
if(isset($_COOKIE['status_message'])){
echo $_COOKIE['status_message'];
set_cookie('status_message','',(time()-3600));
}
This will echo out any populated message and destroy the cookie.
Put your $mesag in query string like this
header("Location:index.php?msg=$mesag");
then use $_GET['msg'] on index.php and get value there and display it.
Related
I working on two pages, a first one which has a form with three fields: name, email and message). This page will send these data to a second page, that will validate if those fields meet the criteria.
If on the second page, any of those fields does not meet the criteria, I want to redirect to the first page (or a third php one), fill the form with previous information and tell the user to correct the fields properly.
I'm strugling to send the data form the second page to the first (or third) one. Does anyone knows a good way to do it?
Here's my code:
First page - contato.html
<form action="validate.php" method="POST" name="emailform">
<div class="form-group">
<input type="text" id="name" name="nome" placeholder="Type your name">
</div>
<div class="form-group">
<input type="text" id="email" name="email" placeholder="type your#email.com here">
</div>
<div class="form-group">
<textarea class="form-control" cols="30" rows="10" maxlength="300" id="message" name="mensagem" placeholder="Leave your message." ></textarea>
</div>
<div class="form-group">
<input type="submit" name="submit" value="Send message" onclick="alert('Thank you!')" ></form>
Second Page - validate.php
if(isset($_POST['nome'])) $nome = $_POST['nome'];
if(isset($_POST['email'])) $email_visitante = $_POST['email'];
if(isset($_POST['mensagem'])) $mensagem = $_POST['mensagem'];
// if does not meet the criteria, redirect to contato.html and update the form with the info
if(empty($nome)){
Header("location:contato.html");
}
if(empty($email_visitante)){
Header("location:contato.html");
}
if(empty($mensagem)){
Header("location:contato.html");
}
// check for letters and space only
if (!preg_match("/^[a-zA-Z ]*$/",$nome)) {
Header("location:contato.html");
}
// check if e-mail address is well-formed
if (!filter_var($email_visitante, FILTER_VALIDATE_EMAIL)) {
Header("location:contato.php");
}
Does anyone knows how to do it? Either sending to a third page or redirecting to the first one (and fill the form in again)
You have to use sessions and store data there in one page and access in another, here is a small usage
<?php
// page 1
session_start();
// Set session variables
$_SESSION["nome"] = $nome;
$_SESSION["email"] = $email_visitante;
$_SESSION["mensagem"] = $mensagem;
<?php
// page 2|3|N - any other page
session_start();
// Get session variables
$nome = $_SESSION["nome"];
$email_visitante = $_SESSION["email"];
$mensagem = $_SESSION["mensagem"];
Part of your problem is that upon any failed validation you are using a redirect. Alternatively you can display an error message to the user: suggesting they need to correct their input by going back a page (browser back).
When forms get longer users need some hand holding with error correction. Their errors need to be clearly indicated with a message alongside as to how they can fix it.
Avoiding using the 'browser back' method above it's common to have the form send to its own url. I've included an example below.
By doing this you can repopulate the form with posted values upon error and add error feedback. You must be careful to escape user input in this situation.
I've added a generic error feedback notice. Which isn't that helpful in its current form. You could improve upon this by adjusting the validation code to return an array of error notices and use that within your form for more targeted error feedback. You could also add - all fields are required - text to help the user.
Upon successful validation that's when to redirect the user to a confirmation page. This can prevent form resubmissions.
Your name regex pattern in its current form will not allow hyphens or apostrophes. I haven't changed it below. Do bear this in mind. "Michael O'leary" would be faced with an error and likely not understand why. You need to be careful when using strict rules for user input. Also this will reject some unicode.
You also need to escape user input appropriately. Note that you may be satisfied that the name and email after validation follows a particular pattern, but becareful of raw user input. The message text is passed on raw after validation.
<?php
$nome = $_POST['nome'] ?? null;
$email_visitante = $_POST['email'] ?? null;
$mensagem = $_POST['mensagem'] ?? null;
$feedback = null;
if(isset($_POST['submit'])) {
if(validate($nome, $email_visitante, $mensagem) !== false) {
process($nome, $email_visitante, $mensagem);
// Redirect to success/thankyou/confirmation page.
header('location:success.html');
exit;
}
// This is a generic message, could this be more helpful?
$feedback = 'Your form has errors. Please correct them.';
}
form($nome, $email_visitante, $mensagem, $feedback);
function process($nome, $email_visitante, $mensagem) {
// do something with your values.
}
function validate($nome, $email_visitante, $mensagem) {
if(empty($nome)) {
return false;
}
if(empty($email_visitante)){
return false;
}
if(empty($mensagem)){
return false;
}
if (!preg_match("/^[a-zA-Z ]*$/",$nome)) {
return false;
}
if (!filter_var($email_visitante, FILTER_VALIDATE_EMAIL)) {
return false;
}
return true;
}
function form($nome = null, $email_visitante = null, $mensagem = null, $feedback = null) {
?>
<?= $feedback ?>
<form action='' method='POST' name='emailform'>
<div class='form-group'>
<label for='name'>Your name:</label>
<input type='text' id='name' name='nome' value='<?= htmlspecialchars($nome) ?>'>
</div>
<div class='form-group'>
<label for='email'>Your email address:</label>
<input type='text' id='email' name='email' value='<?= htmlspecialchars($email_visitante) ?>'>
</div>
<div class='form-group'>
<label for='message'>Your message:</label>
<textarea class='form-control' cols='30' rows='10' maxlength='300' id='message' name='mensagem'><?= htmlspecialchars($mensagem) ?></textarea>
</div>
<div class='form-group'>
<input type='submit' name='submit' value='Send message'>
</div>
</form>
<?php
}
I am creating a Guestbook in PHP, each IP will only be able to post once.
Except for that it will require name and message before sending, and also CAPTCH validation. Somehow my code does ignore the Captcha validation as long as something is written in the input, regardless of what.
I have tried to save the captch in session, and validate the input for the captcha but it doesnt help.
Code to generate the captcha:
function generateCaptchaString($length = 5) {
$captchaString = substr(str_shuffle(str_repeat($x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ', ceil($length/strlen($x)) )),1,$length);
$_SESSION["captchaString"] = $captchaString;
return $captchaString;
}
Code to input name, message and captcha:
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST"
id="guestform">
<fieldset>
<legend>Skriv i gästboken</legend>
<label>Från: </label>
<input type="text" placeholder="Skriv ditt namn"
name="name">
<br>
<label for="text">Inlägg</label>
<textarea id="text" name="message"
rows="10" cols="50"
placeholder="Skriva meddelande här"></textarea>
<br>
<label>Captcha: <span class="red" id="captchastring"><?php
echo generateCaptchaString(); ?></span></label>
<input type="text" placeholder="Skriva captcha här"
name="captcha" id="captchainput" required>
<button type="submit" id="submit">Skicka</button>
</fieldset>
</form>
Code in the POST-function that will check for validation.
if( ! isset($_POST['captcha']) || empty($_POST['captcha']) ||
$_POST['captcha'] != $_SESSION['captcha']) {
$error .= "<p class=\"message-error\">" . $messages['math_invalid'] . "
</p>";
}
In your generateCaptchaString() function, you store the captcha string in $_SESSION["captchaString"].
But in the POST-validation code, you read it as: $_SESSION['captcha']
Change that into $_SESSION["captchaString"] as well.
Also, are you sure the URL to go to when submitting the form is $_SERVER['PHP_SELF'] (which may be another .php script that includes or requires this one) rather than $_SERVER['REQUEST_URI'] which is the same URL you're currently visiting.
Also, if the POST check code is in (or included by) the same file that also contains or includes the form, is it possible that generateCaptchaString() gets called again (to create the form again) thus overwriting any previous captchaString stored there?
I'm a little puzzled with how to implement the Post/Redirect/Get pattern in PHP. I've seen a few answers saying just add the header function after you've submitted the form; I've done that but upon validating whether the input fields are empty, it doesn't print anything although I've added the header function after it's ran the code. I simply cannot find how to integrate this, so I'm asking anyways.
<?php
require '../BACKEND/DB/DB_CONN.php';
if(isset($_POST['submit-register'])) {
if(empty($_POST['email'])) {
echo 'Email cannot be nothing.';
}
header("Location: index.php");
die();
}
if(isset($_POST['submit-login'])) {
if(empty($_POST['loginUser'])) {
echo 'Field Empty.';
}
header("Location: index.php");
die();
}
?>
<div class="forms">
<form method="post" action="index.php" role="form" class="forms-inline register ">
<h4>Register</h4>
<input type="text" name="email" placeholder="Email Address" autocomplete="off" />
<input type="text" name="username" placeholder="Username" autocomplete="off" />
<input type="password" name="password" placeholder="Password" autocomplete="off" />
<input type="submit" name="submit-register" value="Register" role="button" name="login-btn" />
</form>
<form method="post" action="index.php" role="form" class="forms-inline login ">
<h4>Login</h4>
<input type="text" name="loginUser" placeholder="Username" />
<input type="password" name="loginPass" placeholder="Password" />
<input type="submit" name="submit-login" value="Register" role="button" />
</form>
</div>
I was writing the code, but as I've found out it doesn't work, I'm asking how to fix this and how to implement the Post/Redirect/Pattern securely and I know it works.
See the submit-register POST operation validates and redirect to index.php by passing the validation message. You need to GET your message passed from header method.
In PRG Pattern when you do POST operation that has the data but when you redirect and do GET after post to maintain PRG, you have to pass your data to last destination GET url.
In your Code, see both way I have done, first one passes your message to index but second one not PRG when error occurs in validation.
//PRG..........................................
if(isset($_POST['submit-register'])) {
if(empty($_POST['email'])) {
echo 'Email cannot be nothing.';
$msg = "Email cannot be nothing";
}
header("Location: index.php?msg=$msg");
//Get your this message on index by $_GET //PRG
}
//Not full PRG with no passing data to destination.........................
if(isset($_POST['submit-login'])) {
if(empty($_POST['loginUser'])) {
echo 'Field Empty.';
}
else{
header("Location: index.php");
}
}
Note That there should not be any thing printed on page before header method. This means simply no echo before header method.
See first one is PRG and second one is also PRG but not with your data passed to destination.
header("Location: index.php?msg=$msg");
Using header(path) resets the page.
Therefore, any echos printed before would be discarded.
I'm basically trying to create a form that collects a users name, email and company, mails that information to me, and then opens up a secret page to them. I think I'm on the right track, hoping you guys can help me out.
Form:
<form id="form1" action="submit.php" method="post">
<label for="name-id" >Full Name</label>
<input id="name-id" name="name-id" type="text"/>
<label for="email-id" >Email</label>
<input id="email-id" name="email-id" type="text"/>
<label for="company-id" >Company Name</label>
<input id="company-id" name="company-id" type="text"/>
<input type="submit"/>
</form>
PHP:
<?php
$name = $_POST["name-id"];
$email = $_POST["email-id"];
$company = $_POST["company-id"];
if($name != null && $company != null && filter_var($email, FILTER_VALIDATE_EMAIL){
echo "all forms filled";
mail("me#me.com", "subject - success", "body - someone passed");
include ("secretpage.php");
exit();
} else {
include ("homepage.php");
} ?>
Max,
You should redirect your customer to secretpage or homepage instead of include files in a same page.
You can do it by using javascript, window.location="secretpage.php" or window.location="homepage.php" depends upon an authentication.
If your code is not working remove "filter_var($email, FILTER_VALIDATE_EMAIL)" from your if condition. write error_reporting(E_ALL) and ini_set("display_errors",1) at the top of your page code, which will help to track an error.
I am new with php, but I have already made a registration script that works fine. But the problem is every time I press the submit button to check my error, I'm going to a new page.
My question is how I make that error comes on the same page?
The code I am useing for the html form.
I want the error display in the error div box that I made Any idea ?
<div id="RegistrationFormLayout">
<h1>Registration Page</h1>
<div id="ErrorMessage"></div>
<form action="script/registration.php" method="post">
<label for="Username">Username</label>
<input type="text" name="Regi_username">
<label for="FirstName">FirstName</label>
<input type="text" name="Regi_Firstname">
<label for="LastName">LastName</label>
<input type="text" name="Regi_Lastname">
<label for="EamilAddress">Regi_EmailAddres</label>
<input type="text" name="Regi_EmailAddres">
<label for="Password">Password</label>
<input type="password" name="Regi_password">
<button type="submit" value="Submit" class="Login_button">Login</button>
</form>
</div>
If I understand correctly, you want form validation errors there. This is a very common pattern, and the simple solution is to always set a form's action attribute to the same page that displays the form. This allows you to do the form processing before trying to display the form (if there are $_POST values). If the validation is successful, send a redirect header to the "next step" page (with header()).
The basic pattern looks like this (in very very simplified PHP)
<?php
if(count($_POST)) {
$errors = array();
$username = trim($_POST['Regi_username']);
if(empty($username)) {
$errors[] = 'username is required';
}
if(count($errors) == 0) {
header('Location: success.php');
die();
}
}
<ul class="errors">
<?php foreach($errors as $error) { ?>
<li><?php echo $error;?></li>
<?php } ?>
</ul>