12

Upfront apology. Today is my first day working with php and I finally figured out how to get my page to post back to itself (I'd had the page as .html, instead of .php), but now I'm having trouble figuring out how to take the data to a new page after the form has been validated. I've been working on it for quite a while and I'm fried. Here's a simple example:

<!DOCTYPE HTML>
<html>
<head>
<style>
.error {color: #FF0000;}
</style>
</head>
<body>

<?php
// Initialize variables and set to empty strings
$firstName=$lastName="";
$firstNameErr=$lastNameErr="";

// Validate input and sanitize
if ($_SERVER['REQUEST_METHOD']== "POST") {
   if (empty($_POST["firstName"])) {
      $firstNameErr = "First name is required";
   }
   else {
      $firstName = test_input($_POST["firstName"]);
   }
   if (empty($_POST["lastName"])) {
      $lastNameErr = "Last name is required";
   }
   else {
      $lastName = test_input($_POST["lastName"]);
   }
}

// Sanitize data
function test_input($data) {
   $data = trim($data);
   $data = stripslashes($data);
   $data = htmlspecialchars($data);
   return $data;
}
?>

<h2>Find Customer</h2>
<p><span class="error">* required</span></p>
<form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']);?>" method="post">
First Name: <input type="text" name="firstName" value="<?php echo $firstName; ?>"><span class="error">* <?php echo $firstNameErr; ?></span><br><br>
Last Name: <input type="text" name="lastName" value="<?php echo $lastName; ?>"><span class="error">* <?php echo $lastNameErr; ?><br><br>
<input type="submit">
</form>

</body>
</html>

OK. So above, you'll see that the form posts back to itself so it can validate. Good. Now, considering all things are valid, how do I post to another script (action="otherAction.php", maybe?) so the data can actually be processed?

Also, any security suggestions are appreciated. I did my best to take security into account. Thanks.

vincent
  • 1,370
  • 2
  • 13
  • 29

4 Answers4

7

When all your conditions are met you can use header('Location: http:mywebsite.com/otherAction.php')

// Validate input and sanitize
if ($_SERVER['REQUEST_METHOD']== "POST") {
   $valid = true; //Your indicator for your condition, actually it depends on what you need. I am just used to this method.

   if (empty($_POST["firstName"])) {
      $firstNameErr = "First name is required";
      $valid = false; //false
   }
   else {
      $firstName = test_input($_POST["firstName"]);
   }
   if (empty($_POST["lastName"])) {
      $lastNameErr = "Last name is required";
      $valid = false;
   }
   else {
      $lastName = test_input($_POST["lastName"]);
   }

  //if valid then redirect
  if($valid){
   header('Location: http://mywebsite.com/otherAction.php');
   exit();
  }
}

In some of my works, my setup is like this but I learned something not good here. That's when you refresh the page after submitting the form , POST values still remains and possible for duplicating entries. Which is not good IMO.

Drixson Oseña
  • 3,631
  • 3
  • 23
  • 36
  • 3
    Noted that you should use `exit()` right after the redirection for security reason. – invisal Sep 16 '13 at 03:43
  • 1
    hi @invisal, will you mind sharing some links. So I can understand more about it. Thanks! – Drixson Oseña Sep 16 '13 at 03:50
  • http://stackoverflow.com/questions/2747791/why-i-have-to-call-exit-after-redirection-through-headerlocation-in-php – invisal Sep 16 '13 at 03:57
  • This works nicely! Thank you! Is this a typical way to process things? I don't want to influence answers too strongly by asking poor questions. – vincent Sep 16 '13 at 03:59
  • @vincent it depends as long as you want your script to be secured and well layout , soon you can just set `valid = false` and let only `valid = true` for one valid condition. As long you write your code in PHP , you will learn a lot of things especially holes in your code.And if you getting the logic behind it , youll be decent on writing codes. This can be one of many ways :) – Drixson Oseña Sep 16 '13 at 04:06
  • 1
    @DrixsonOseña This `header('Location: http:mywebsite.com/otherAction.php')` should be `header('Location: http://mywebsite.com/otherAction.php');` - you missed `//` and ending semi-colon. It's always best to put it in there. – Funk Forty Niner Sep 16 '13 at 13:17
  • Hello @DrixsonOseña, You know how to fetch element after redirecting to another PHP. I am doing `$_POST['loginId']` and getting blank after doing `header('Location: http://localhost:89/tutorial/MyApp/registerUser.php');` from my html file? – Jaikrat Jan 27 '16 at 20:19
  • 2
    @Jaikrat you lost $_POST when you redirect.. there's two way to solve this.. 1.) store id in cookie or 2.) use $_GET add query string in the url for example `mywebsite.com/page/page?userid=12` – Drixson Oseña Jan 28 '16 at 00:22
  • Thanks @DrixsonOseña. Using cookies, I have lots of data to be sent. – Jaikrat Jan 28 '16 at 19:34
6

Use javascript to validate, then send the post form to itself or to another page where it can do stuff with the data.

<!DOCTYPE html>
<html>
<head>
<script>
function validateForm()
{
var x=document.forms["myForm"]["fname"].value;
if (x==null || x=="")
  {
  alert("First name must be filled out");
  return false;
  }
}
</script>
</head>

<body>
<form name="myForm" action="demo_form.php" onsubmit="return validateForm()" method="post">
First name: <input type="text" name="fname">
<input type="submit" value="Submit">
</form>
</body>

</html>

source : http://www.w3schools.com/js/js_form_validation.asp

<!DOCTYPE HTML>
<html>
<head>
<style>
.error {color: #FF0000;}
</style>
</head>
<body>

<?php
// Initialize variables and set to empty strings
$firstName=$lastName="";
$firstNameErr=$lastNameErr="";

// Control variables
$app_state = "empty";  //empty, processed, logged in
$valid = 0;

// Validate input and sanitize
if ($_SERVER['REQUEST_METHOD']== "POST") {
   if (empty($_POST["firstName"])) {
      $firstNameErr = "First name is required";
   }
   else {
      $firstName = test_input($_POST["firstName"]);
      $valid++;
   }
   if (empty($_POST["lastName"])) {
      $lastNameErr = "Last name is required";
   }
   else {
      $lastName = test_input($_POST["lastName"]);
      $valid++;
   }

   if ($valid >= 2) {
      $app_state = "processed";
   }
}

// Sanitize data
function test_input($data) {
   $data = trim($data);
   $data = stripslashes($data);
   $data = htmlspecialchars($data);
   return $data;
}

if ($app_state == "empty") {
?>
<h2>Find Customer</h2>
<p><span class="error">* required</span></p>
<form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']);?>" method="post">
First Name: <input type="text" name="firstName" value="<?php echo $firstName; ?>"><span class="error">* <?php echo $firstNameErr; ?></span><br><br>
Last Name: <input type="text" name="lastName" value="<?php echo $lastName; ?>"><span class="error">* <?php echo $lastNameErr; ?><br><br>
<input type="submit">
</form>

</body>
</html>
<?php
}
elseif ($app_state == "processed") {
    if ($firstName == "Vincent") {
        $app_state = "Logged in";
    }
}

if ($app_state == "Logged in") {
    echo("Logged in<br> Hello Vincent</body></html>");
}
?>
Lazik
  • 2,480
  • 2
  • 25
  • 31
  • So I should just javascript instead of php to validate form data? – vincent Sep 16 '13 at 03:35
  • It's better that way, the user doesn't have to reload pages if something is wrong with his input. You can still do additional php validation/sanitize on the form landing page. – Lazik Sep 16 '13 at 03:36
  • OK. I got most of this content from w3 [link](http://www.w3schools.com/php/php_form_required.asp), so maybe I'm confused on the usage? If a form needs to be validated before being submitted - say, to a database for querying or insertion - javascript should be used, because an additional php action/direction is ineffecient/incorrect/superfluous? Just want to understand. – vincent Sep 16 '13 at 03:44
  • 1
    @vincent, Javascript is nice feature to have, but it is only optional. PHP is MUST because it is your last defense against awful data. Normally, Javascript can be disable. People can easily bypass Javascript validation. – invisal Sep 16 '13 at 03:45
  • There is no need for a redirect, all logic can take place on the landing php page. – Lazik Sep 16 '13 at 03:59
  • @Lazik can you explain what you mean by that? – vincent Sep 16 '13 at 04:03
  • I've edited my answer, look at the additional code. Keep in mind : each time you reload a page, there is 2-3seconds of additional wait time for you users. Users don't like to wait :) – Lazik Sep 16 '13 at 04:30
  • @Lasik, there is a need for a redirect! If you start with a self verifying form that, upon "submit", and the action="" then how can you ever change to another page when all the data is finally correct? You have to redirect somehow... The problem I've noticed is that all redirect solutions that I've seen (using header() or a javascript redirect) seem to cause problems with the back button in the browser. It seems like there should be a better way. – Damian Green Jul 16 '17 at 22:21
  • I mean there is no need for a redirect. You can if you want. There is a solution for the back button, it's called restful javascript. It allows for the back button correction on the same page. – Lazik Feb 22 '23 at 06:59
0

You can check if there is any invalid data, if there is no invalid data, process, then redirect. For example

 if (empty($firstNameErr) && empty($lastNameErr)) {
       // process the data

       // redirect to other page.
       header('LOCATION: index.php');
       exit();
 }

Noted that you need to do those code before you output any HTML, or else you cannot do the redirection. For example:

<?php
      // validate the data
      // no error, proccess, then, redirect
?>
html code here.
invisal
  • 11,075
  • 4
  • 33
  • 54
  • This should go right under the rest of my if/else processing, right? Is this a more efficient way to do things because a new variable doesn't have to be instantiated? (granted the performance gain will be negligible) Are there other benefits over @Drixson's answer? – vincent Sep 16 '13 at 04:05
  • @vincent, Drixson's answer and my answer is basically using the same concept with a slightly different approach. Typically, Drixson's answer would be faster if there are many fields to validate. Since there are only two fields, the performance different is too too small that it makes no different. (even with plenty of field, the performance different is still too small) – invisal Sep 16 '13 at 04:19
  • @vincent, however, you should add `exit();` right after header redirection because header redirection just send header to user's browser to request for redirection. Bad-intended user can ignore the redirection request. – invisal Sep 16 '13 at 04:21
  • thank you for the explanation - that makes sense. Also, I have added "exit;", per the page you linked. Thank you for advising on the open security vulnerability. – vincent Sep 16 '13 at 05:12
0

Relying on redirection like that is bad for SEO if you are about that stuff. It would be better for SEO for your form to post to another page naturally.

Francisco Aguilera
  • 3,099
  • 6
  • 31
  • 57