$_POST empty on submit - php

I have a registration script (called "script.php") divided in 3 steps; this is the basic structure (i have stripped things out like sanitizing user input and preventing direct access to other steps than 1):
<?php
$step = $_GET['step'];
switch($step) {
case 1:
//show form - action="script.php?step=2" method="post"
break;
case 2:
//if user data is good show an overview of the data and show a button to go to step 3 (the button is enclosed in a form - action="script.php?step=3" and method="post")
//if not, show again form - action="script.php?step=2" method="post" - and display errors
break;
case 3:
//add user data into db
break;
}
?>
Real code:
<?php
switch ($step) {
case 1:
//display form
$html = <<<FORM
<form action="/install?step=2" method="post">
<input type="text" name="username">
<input type="email" name="email">
<input type="password" name="password">
<input type="password" name="password_repeat">
<button class="next" type="submit">Next</button>
</form>
FORM;
break;
case 2:
$errors = array();
if (empty($_POST['username'])||!preg_match_all('/^([A-Za-z0-9]+){1,16}$/', $_POST['username'])) {
$errors[] = 'bad/empty username';
}
if (empty($_POST['email'])||!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
$errors[] = 'bad/empty email';
}
if (empty($_POST['password'])) {
$errors[] = 'empty password';
}
if (empty($_POST['password_repeat'])) {
$errors[] = 'empty password confirm';
}
if ((!empty($_POST['password'])&&!empty($_POST['password_repeat']))&&$_POST['password']!==$_POST['password_repeat']) {
$errors[] = 'passwords do not match';
}
if(count($errors)>0) {
$error_html = 'some errors occurred';
foreach ($errors as $err) {
$error_html .= 'error: '.$err;
}
$form_html = <<<FORM
<form action="/install?step=2" method="post">
<input type="text" name="username" value="{$_POST['username']}">
<input type="email" name="email" id="email" value="{$_POST['email']}">
<input type="password" name="password">
<input type="password" name="password_repeat">
<button class="next" type="submit">Next</button>
</form>
FORM;
$html = $error_html.$form_html;
}
else {
$ent = 'htmlentities';
$html = <<<DATA_OK
<h3>Data overview</h3>
<table>
<tr>
<th>Username:</th>
<td>{$ent($_POST['username'])}</td>
</tr>
<tr>
<th>email:</th>
<td>{$ent($_POST['email'])}</td>
</tr>
<tr>
<th>Password:</th>
<td>{$ent($_POST['password'])}</td>
</tr>
</table>
<form action="/install?step=3" method="post">
<button class="next" type="submit">Avanti</button>
</form>
DATA_OK;
}
break;
case 3:
//connect to db and insert data
break;
}
?>
<!doctype HTML>
<html>
<head>
<title>Script</title>
<meta charset="utf-8">
</head>
<body>
<?php echo $html; ?>
</body>
</html>
The problem is that when i go to step 3 $_POST is always empty. Is the button shown in step 2 (if user data is good) overwriting $_POST? Or is it emptied because that form has no input but only a submit? How can i pass the $_POST data to step 3 without using hidden fields (as they would contain passwords/pw hashes)?
I have searched on google and here on SO but i couldn't find anything related to my problem.

<form action="/install?step=3" method="post">
<button class="next" type="submit">Avanti</button>
</form>
What values do you expect to be posted in Step 3 ? There is none in your form. Even the button does not have a name attribute. No fields inside a form with name attribute will sent an EMPTY post.
POST data can be disposed the same way as the hidden fields. The one who posts can see what he posts, so there is no reason to hide it from him. If he has posted password from step 1, he knows what he has posted. You can hash it, and set it into a session/hidden fields, even thought it's bad practice.
I, really, don't understand why do you have 2 steps. If step 2 is only having a button, why do you have it? You can make the validation in step 1, and if it is OK, go to step 3, if not - stay.

Related

echo an error without redirecting to another page and keep all form data?

If for example a username isn't filled in the user is given an error stating so, but after pressing submit they're thrown to another page with the error.
How would I go around keeping the error on the same page as the registration form and keeping all the text entered by the user after submit?
Registration PHP:
<?php
require 'db_connect.php';
$count = 0;
if (isset($_POST['username']))
{
$username = $_POST['username'];
if (!empty($username))
{
$count++;
}
else
{
echo 'Please enter a username';
echo "<br>";
}
}
if (isset($_POST['email']))
{
$email = $_POST['email'];
if (!empty($email))
{
$count++;
}
else
{
echo 'Please enter an email';
echo "<br>";
}
}
if (isset($_POST['password']))
{
$password = $_POST['password'];
if (!empty($password))
{
$count++;
}
else
{
echo 'Please enter a password';
echo "<br>";
}
}
if(strlen($username) > 25)
header('Location: registration.php');
$hashword = password_hash($password,PASSWORD_DEFAULT);
if($count == 3 )
{
$query = "INSERT INTO member ( username, password, email)
VALUES ( '$username', '$hashword', '$email');";
header('Location: login.html');
}
else {
echo '<b>You will be redirected shortly</b>';
echo "<br>";
echo '<b>Please enter ALL details correctly</b>';
header( "refresh:5;url=registration.php" );
}
$result = mysqli_query($connection, $query) or die(mysqli_error($connection));
?>
Registration Form:
<!doctype html>
<html lang="en">
<head>
<title>Gumby template file</title>
<meta charset="utf-8" />
<script data-touch="gumby/js/libs" src="gumby/js/libs/gumby.min.js"></script>
<script src="gumby/js/libs/jquery-2.0.2.min.js"></script>
<link rel="stylesheet" href="gumby/css/gumby.css">
<script src="gumby/js/libs/modernizr-2.6.2.min.js"></script>
<link rel="stylesheet" href="forumhomepage_style.css">
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
</head>
<body>
<form name="register" action="register.php" method="post">
<tr>
<td>Username: </td>
<td><input type="text" name="username" maxlength="25" /></td>
</tr>
<tr>
<td>Email: </td>
<td><input type="text" name="email" id="email" /></td>
</tr>
<tr>
<td>Password: </td>
<td><input type="password" name="password" /></td>
</tr>
<tr>
<td> </td>
<td><input type="submit" value="Register" /></td>
</tr>
</table>
</form>
</body>
</html>
It depends on at what level do you want to do this.
Validating that the different data is not empty and has information that makes sense (like the password is at least 7 chars long) can be done via javascript before sending the form data, this way you can stop the form to be sent. You can use jQuery Plugin Validator to help you do this.
But other validations like the insert has failed only can be done at server side, if you need also not to redirect in this case then you have to use ajax to load the data and then refresh the website info without reloading it.
I prefer to only do an initial check with javascript and send the user to the results page. But I also keep the validations as this one of the password length in the php because, even though now a days it's really strange, a user can disable javascript and I don't wana have surprises when checking the database values. But, another example, if you have lots of users you could check that the user does not exist to warn the user at the very first moment before the form is sent and this can only be done performing an ajax call.
You should know how to do both things and decide depending on what you want to do on your projects.
In your case, I would leave the php validations as they are now and check the same (non empty values) in javascript on the form submit event calling event.preventDefault() if an error has been detected.
$('form[name="register"]').submit(function( event ) {
if ($('input[name="username"]').is(":empty")) {
// append a "Username can not be empty message somewhere on your page
event.preventDefault();
}
// I let you finish the jquery code...
});
This example uses jQuery lib. but you can do it without it with just javascript if you want.
There are several ways to do this. The first step is using the required attribute in your input elements:
<input type="text" name="username" required>
This will force the user to at least put something inside the input element. Then there's Javascript or jQuery for client side validation. You can create a custom event handler to catch the form submit and validate the input like so:
document.getElementById("your_form_id_here").addEventListener("submit", function(e){
// Your Javascript validation code here, for example:
var x = document.forms["your_form_id_here"]["username"].value;
if (x == "") {
alert("Username must be filled out");
e.preventDefault();
}
});
You can also put the form handler on the same file as the form and display the errors / values in case something goes wrong. For example:
<?php
if(!empty($_POST['submit'])){
$error = false;
if($_POST['username'] === ''){
$usernameEmpty = 'The username was empty. Please enter a username!';
$error = true;
}
if(!$error){
// No errors found so proceed with the registration
}
}
?>
<form id="myForm" method="post" action="" accept-charset="utf-8">
<?php if(!empty($usernameEmpty)){ echo $usernameEmpty . '<br/>'; } ?>
Username: <input type="text" name="username" value="<?php if(!empty($_POST['username'])){ echo $_POST['username']; } ?>"/>
<input type="submit" name="submit" value="Register"/>
</form>
Lastly there's of course Ajax which will allow you to send the form towards PHP without reloading your page. You could have PHP send the errors back and use Javascript to show the errors inside the DOM.
without ajax you will need ro lead your page with some conditional logic. This will look and see if any fields are filled in and fill them in again, along with setting any error messages to return to the user.
something like:
<?php
//example fields
$username = '';
$field2 = '';
$field3 = '';
if(isset($errorToShow)){
// echo your error message here
}
if($_POST["submit"]){
foreach($_POST as $k=>$v){
$$k = $v;
}
}
// your form can be here.
of course there are other considerations and ajax is a better solution, but this type of thing can work just fine.
You may use ajax
Or if you don't know ajax
You can put all your code in one page and call $_POST indexes into the value of every input.
for ex.
<input type="text" name="username" maxlength="25" value="<?=$_POST['usename'];?>"/>
Or you may use "PHP $_SESSION"
Just store $_POST into $_SESSION
then call it from the html page
for ex.
<input type="text" name="username" maxlength="25" value="<?=$_SESSION['usename'];?>"/>
And the same idea for errors.

Problems with contact form functionality in php

Before You read the code, I have tried separating each part into their own php files and just using requires to fetch the code, but using requires or having all the code in the same file I seem to be getting the same errors regardless. I think it may have something to do with the the version of PHP I'm using.
I seem to be getting an error with submit on line 3 of the BACKEND part. Being an undefined property.
The second is an undefined error on the USER FEEDBACK section.
I've used this template before and has worked successfully.
I'm running PHP 5.4.12 and Apache 2.4.4 using WAMP on my Windows 8.1 Pro PC.
Any help would be appreciated
/** BACKEND **/
<?php
if($_POST['submit'])
{
$fName=$_POST['fName'];
$topic=$_POST['topic'];
$email=$_POST['email'];
$message=$_POST['message'];
function verify_email($email)
{
if(!preg_match('/^[_A-z0-9-]+((\.|\+)[_A-z0-9-]+)*#[A-z0-9-]+(\.[A-z0-9-]+)*(\.[A-z]{2,4})$/',$email))
{
return false;
}
else
{
return $email;
}
}
function verify_email_dns($email)
{
list($name, $domain) = split('#',$email);
if(!checkdnsrr($domain,'MX'))
{
return false;
}
else
{
return $email;
}
}
if(verify_email($email))
{
if(verify_email_dns($email))
{
if ($fName=='')
{
header('location:./contact.php?error=missing');
}
elseif ($email=='')
{
header('location:./contact.php?error=missing');
}
elseif ($message=='')
{
header('location:./contact.php?error=missing');
}
else
{
foreach ($myvars as $var)
{
if (isset($_POST[$var]))
{
$var=$_POST[$var];
}
}
$subject = "Email Submission for review";
$add.="test.email#gmail.com";
$msg.="First Name: \t$fName\n";
$msg.="Email: \t$email\n";
$msg.="Topic: \t$topic\n";
$msg.="Message: \t$message\n";
$mailheaders="From: $email\n";
$mailheaders.="Reply-To: $email\n";
mail("$add", "$subject", $msg, $mailheaders);
header('location:./contact.php?error=none');
}//end else
}//end inner-if
else
{
header('location:./contact.php?error=mx');
}
}// end outter-if
else
{
header('location:./contact.php?error=format');
}
}// end starting if
/** VIEW for form **/
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" name="contactForm">
<label for="fName" class="first-name">Name:</label>
<input type="text" name="fName" value="" id="fName">
<br><br>
<label for="email" class="email-name">Email:</label>
<input type="text" name="email" value="" id="email">
<br><br>
<label for="topic" class="subject-name">Subject:</label>
<input type="text" name="topic" value="" id="topicsubject">
<br><br>
<label for="message" class="message-name">Message:</label>
<textarea name="message" rows="5" cols="60" id="message"></textarea>
<br><br>
<input type="submit" name="submit" id="submit-btn" class="submit-btn" value="Email Me">
</form>
/** USER FEEDBACK if error occurs **/
<?php
$error=$_GET['error'];
switch ($error)
{
case "mx":
echo "<br><span class='red'>Your email address you entered is invalid. Please try again.</span><br>";
break;
case "format":
echo "<br><span class='red'>Your email address is not in the correct format, it should look like name#domain.com. Please try again.</span><br>";
break;
case "missing":
echo "<br><span class='red'>You seem to be missing a required field, please try again.</span><br>";
break;
case "none":
echo "<br>Your email was sent. I will get back to you as soon as I can. Thank you for your interest.<br>";
break;
default:
echo "<br><br>";
}
?>
You are assuming that there are POST and GET variables when you are visiting the page. So its possible that $_POST['submit'] only exists when you actually submit the form otherwise you will get an error when first visiting that page.
try this condition instead:
if(isset($_POST['submit']) ) {
// now its safe to do something
}
You should never assume that any $_POST or $_GET variable is available when visiting the page.
Also off topic:
In your HTML you are using an 'action' attribute with the same url as the page you are visiting on this line here:
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" name="contactForm">
Basically if you just leave out the action attribute all together it will have the same effect and its also semantic to do so. This is a better way of doing it and it has the same effect:
<form method="post" name="contactForm">
You can check this previous Stack Overflow question for a better explanation on that matter:
Is it a good practice to use an empty URL for a HTML form's action attribute? (action="")

PHP error display

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>

PHP Show error messages in order and re-display correct fields

I have an email form that checks three fields, name, valid email and comments. But the way it's set up now, since name and comments are in one function it first checks name and comments even if email is not valid, how can I re-write it so it checks the fields in order. Also, I would like to re-display the fields that have no errors, so the user doesn't have to type again. Please help. Thanks
<?php
$myemail = "comments#myemail.com";
$yourname = check_input($_POST['yourname'], "Enter your name!");
$email = check_input($_POST['email']);
$phone = check_input($_POST['phone']);
$subject = check_input($_POST['subject']);
$comments = check_input($_POST['comments'], "Write your comments!");
if (!preg_match("/([\w\-]+\#[\w\-]+\.[\w\-]+)/", $email))
{
show_error("Enter a valid E-mail address!");
}
exit();
function check_input($data, $problem='')
{
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
if ($problem && strlen($data) == 0)
{
show_error($problem);
}
return $data;
}
function show_error($myError)
{
?>
<!doctype html>
<html>
<body>
<form action="myform.php" method="post">
<p style="color: red;"><b>Please correct the following error:</b><br />
<?php echo $myError; ?></p>
<p>Name: <input type="text" name="yourname" /></P>
<P>Email: <input type="text" name="email" /></p>
<P>Phone: <input type="text" name="phone" /></p><br />
<P>Subject: <input type="text" style="width:75%;" name="subject" /></p>
<p>Comments:<br />
<textarea name="comments" rows="10" cols="50" style="width: 100%;"></textarea></p>
<p><input type="submit" value="Submit"></p>
</form>
</body>
</html>
<?php
exit();
}
?>
First off, I would suggest you validate ALL of the fields at once, and display all appropriate error messages on the form. The primary reason is that it can be bad user experience if they have to submit your form a whole bunch of times because they have to address one error at a time. I'd rather correct my email address, password, comments, and selection in one try instead of fixing one at a time just to reveal what the next error is.
That said, here are some pointers on validating the form like you want. This is typically how I approach a form doing what you want to do. This assumes your form HTML and form processor (PHP) are together in the same file (which is what you have now). You can split the two, but the methods for doing that can be a bit different.
Have one function or code block that outputs the form and is aware of your error messages and has access to the previous form input (if any). Typically, this can be left outside of a function and can be the last block of code in your PHP script.
Set up an array for error messages (e.g. $errors = array()). When this array is empty, you know there were no errors with the submission
Check to see if the form was submitted near the top of your script before the form is output.
If the form was submitted, validate each field one at a time, if a field contained an error, add the error message to the $errors array (e.g. $errors['password'] = 'Passwords must be at least 8 characters long';)
To re-populate the form inputs with the previous values, you have to store the entered values somewhere (you can either just use the $_POST array, or sanitize and assign the $_POST values to individual variables or an array.
Once all the processing is done, you can check for any errors to decide whether the form can be processed at this point, or needs new input from the user.
To do this, I typically do something like if (sizeof($errors) > 0) { // show messages } else { // process form }
If you are re-displaying the form, you simply need to add a value="" attribute to each form element and echo the value that was submitted by the user. It is very important to escape the output using htmlspecialchars() or similar functions
With those things in place, here is some re-work of your form to do that:
<?php
$myemail = "comments#myemail.com";
$errors = array();
$values = array();
$errmsg = '';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
foreach($_POST as $key => $value) {
$values[$key] = trim(stripslashes($value)); // basic input filter
}
if (check_input($values['yourname']) == false) {
$errors['yourname'] = 'Enter your name!';
}
if (check_input($values['email']) == false) {
$errors['email'] = 'Please enter your email address.';
} else if (!preg_match('/([\w\-]+\#[\w\-]+\.[\w\-]+)/', $values['email'])) {
$errors['email'] = 'Invalid email address format.';
}
if (check_input($values['comments']) == false) {
$errors['comments'] = 'Write your comments!';
}
if (sizeof($errors) == 0) {
// you can process your for here and redirect or show a success message
$values = array(); // empty values array
echo "Form was OK! Good to process...<br />";
} else {
// one or more errors
foreach($errors as $error) {
$errmsg .= $error . '<br />';
}
}
}
function check_input($input) {
if (strlen($input) == 0) {
return false;
} else {
// TODO: other checks?
return true;
}
}
?>
<!doctype html>
<html>
<body>
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
<?php if ($errmsg != ''): ?>
<p style="color: red;"><b>Please correct the following errors:</b><br />
<?php echo $errmsg; ?>
</p>
<?php endif; ?>
<p>Name: <input type="text" name="yourname" value="<?php echo htmlspecialchars(#$values['yourname']) ?>" /></P>
<P>Email: <input type="text" name="email" value="<?php echo htmlspecialchars(#$values['email']) ?>" /></p>
<P>Phone: <input type="text" name="phone" value="<?php echo htmlspecialchars(#$values['phone']) ?>"/></p><br />
<P>Subject: <input type="text" style="width:75%;" name="subject" value="<?php echo htmlspecialchars(#$values['subject']) ?>" /></p>
<p>Comments:<br />
<textarea name="comments" rows="10" cols="50" style="width: 100%;"><?php echo htmlspecialchars(#$values['comments']) ?></textarea></p>
<p><input type="submit" value="Submit"></p>
</form>
</body>
</html>
I have a more advanced example which you can see here that may give you some guidance as well.
Hope that helps.
The simplest option is to use a form validation library. PHP's filter extension, for example, offers validation and sanitization for some types, though it's not a complete solution.
If you insist on implementing it yourself, one issue you'll have to consider is what counts as the order: the order of the elements in the form or the order of the user input in $_POST. On most browsers, these should be the same, but there's no standard that enforces this. If you want to go off of form order, you'll need to define the form structure in one place, and use that information to do things like generating or validating the form (a consequence of the Don't Repeat Yourself (DRY) principle). Iterating over the appropriate structure will give you the order you desire: looping over the form gives you form order, whereas looping over $_POST gives you user input order.
It looks like you want to more than simply validate the data; you also want to prepare it for use, a process called "sanitization".
When it comes to sanitization, define different kinds of sanitizers, rather than a single check_input function. Specific sanitizers could be functions, or objects with an __invoke method. Create a map of form fields to sanitizers (for example, an array of input name to sanitizer callbacks). The order of the elements in the mapping sets the order of the sanitization; if you use a single structure to define the form information, the display order and sanitization order will thus be the same.
Here's a very broad outline:
# $fields could be form structure or user input
foreach ($fields as $name => $data) {
# sanitize dispatches to the appropriate sanitizer for the given field name
$form->sanitize($name, $data);
# or:
//sanitize($name, $data);
# or however you choose to structure your sanitization dispatch mechanism
}
As for setting an input's value to the user-supplied data, simply output the element value when outputting the element. As with all user input (really, all formatted output), properly escape the data when outputting it. For HTML attributes, this means using (e.g.) htmlspecialchars. Note you should only escape outgoing data. This means your sanitization functions shouldn't call htmlspecialchars.
You can improve usability by placing each error next to the corresponding input, adding an "error" class to the element and styling the "error" class to make it stand out. Improve accessibility by wrapping <label> elements around the label text.
Use this structure of script:
<?php
$errors = array();
if (isset($_POST['send'])) {
// check data validity
if (!mailValid($_POST['email']))
$errors[] = 'Mail is not valid';
...
// send data by email
if (!$errors) {
// send mail and redirect
}
}
?>
<html>
...
<?php
if ($errors) {
// display errors
foreach ($errors as $error) {
echo "$error<br />";
}
}
?>
<form ...>
...
Email: <input type="text" name="email" value="<?php echo isset($_POST['email']) ? htmlspecialchars($_POST['email']) : '' ?>" />
...
</form>
...
</html>
You could always do it like this, using filter_var and in_array checks:
<?php
$myemail = "comments#myemail.com";
//Pre made errors array
$errors=array('name'=>'Enter Your name',
'email'=>'Please enter valid email',
'phone'=>'Please enter valid phone number',
'subject'=>'Please enter valid subject, more then 10 chars',
'comment'=>'Please enter valid comment, more then 10 chars');
//Allowed post params and its validation type
$types = array('name'=>'string',
'email'=>'email',
'phone'=>'phone',
'subject'=>'string',
'comment'=>'string');
//A simple validation function using filter_var
function validate($value,$type){
switch ($type){
case "email":
return ((filter_var($value, FILTER_VALIDATE_EMAIL))?true:false);
break;
case "phone":
return ((preg_match("/^[0-9]{3}-[0-9]{4}-[0-9]{4}$/", $value))?true:false);
break;
case "string":
return ((strlen($value) >=10 )?true:false);
break;
default:
return false;
break;
}
}
//If forms been posted
if(!empty($_POST) && $_SERVER['REQUEST_METHOD'] == 'POST'){
//Assign true, if all is good then this will still be true
$cont=true;
$error=array();
foreach($_POST as $key=>$value){
//if key is in $types array
if(in_array($key,$types)){
//If validation true
if(validate($value, $types[$key])==true){
$$key=filter_var($value, FILTER_SANITIZE_STRING);
}else{
//Validation failed assign error and swithc cont to false
$error[$key]=$errors[$key];
$cont=false;
}
}
}
}
if($cont==true && empty($error)){
//Send mail / do insert ect
}else{
//Default to form
?>
<!doctype html>
<html>
<body>
<form action="" method="post">
<p>Name: <input type="text" name="name" value="<?=#htmlentities($name);?>"/> <?=#$error['name'];?></P>
<P>Email: <input type="text" name="email" value="<?=#htmlentities($email);?>" /> <?=#$error['email'];?></p>
<P>Phone: <input type="text" name="phone" value="<?=#htmlentities($phone);?>"/> <?=#$error['phone'];?></p><br />
<P>Subject: <input type="text" style="width:75%;" name="subject" /> <?=#$error['subject'];?></p>
<p>Comments: <?=#$error['comment'];?><br />
<textarea name="comment" rows="10" cols="50" style="width: 100%;"><?=#htmlentities($comment);?></textarea></p>
<p><input type="submit" value="Submit"></p>
</form>
</body>
</html>
<?php
}?>

Avoid code re-use when handling form validation

I am generating form and handling the submit event in the same file.
If user has not entered the title, I want to display the form again and include an error message (e.g. "You forgot the title.").
That means that I have to duplicate code twice - once to diplay empty form and second to display form with body and ask user to enter title:
<?php if(strlen(strip_tags($_POST['posttitle'])) == 0):
// Display the form with question body that user has entered so far and ask user to enter title.
?>
<label for="title"><b>Title:</label><br/>
<input type="text" name="posttitle" id="posttitle" />
<?php endif;?>
<?php elseif ( 'POST' == $_SERVER['REQUEST_METHOD'] && !empty( $_POST['action']) && $_POST['action'] == 'post') : ?>
<!-- Everything ok - insert post to DB -->
<?php else :
// just display form here (again ouch!)
<label for="title"><b>Title:</label><br/>
<input type="text" name="posttitle" id="posttitle" />
?>
I would do it like this:
If REQUEST_METHOD is POST I will validate the input and collect messages in an array ($errors in my code).
Then I would just print the form and if there was an error the code will print it.
<?php
$errors = array();
function print_value_for($attr) {
if (isset($_POST[$attr]))
echo $_POST[$attr];
}
function print_error_for($attr) {
global $errors;
if (isset($errors[$attr]))
echo $errors[$attr];
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// do validation here and add messages to $errors
// like $errors['posttitle'] = "The title you entered is bad bad bad";
if (empty($errors)) {
// update database and redirect user
}
}
?>
<!-- display the form and print errors if needed -->
<form>
<?php print_error_for('posttitle'); ?>
<input name="posttitle" type="text" value="<?php print_value_for('posttitle') ?>">
<?php print_error_for('postauthor'); ?>
<input name="postauthor" type="text" value="<?php print_value_for('posttitle') ?>">
<?php print_error_for('postbody'); ?>
<textarea name="postbody">
<?php print_value_for('posttitle') ?>
</textarea>
<input type="submit">
</form>
PS. Consider using MVC to separate code and templates.
Here is a quick way to do that.
<form>
<input type="text" name="title" value="<?php echo $_REQUEST['title']; ?>"/>
<input type="text" name="field_a" value="<?php echo $_REQUEST['field_a']; ?>"/>
....
</form>
But I can also advise you to display a var called $title which is the result of a check on $_REQUEST['title].
You could use an output buffer to grab the form and then assign it to a variable like so:
<?php
ob_start();
include('path/to/your/form');
$form = ob_get_flush();
// then later you can just go
print $form;
?>
Hope this helps
When you display the form, use the possibly empty $_POST values as default field values for both the title and question body. If either is empty, the form will display the second time with the other already filled in:
<?php
$message = "";
if (empty($_POST['title'])) $message .= " Please enter a title.";
if (empty($_POST['body'])) $message .= " Please enter a body.";
?>
<form action='me.php'>
<input name='title' type='text' value='<?php if (!empty($_POST['title'])) echo htmlentities($_POST['title'], ENT_QUOTES); ?>' />
<textarea name='body'><?php if (!empty($_POST['body'])) echo $_POST['body']; ?></textarea>
</form>
Read this MVC
Your can write form in view, handler in controller, and business logic in model

Categories