how to maintain post variables inbetween pages - php

Possibly stupid question time:
On many websites, when a user submits a form, the information is checked, and if it is incorrect they are redirected back to the form, with all/most of the information still intact and entered into the form. E.g. they type in the wrong password, but after the redirect, their username is still intact in the form. I want to know the best method in which this can be done.
I did some testing:
post1.php:
<?php
$_POST['user']='name';
header('Location: post2.php');
?>
post2.php:
<?php
if(!empty($_POST['user'])){
header('Location: post3.php');
//echo 'post: '.$_POST['user'];
}
else{
echo 'nope post2.';
}
?>
post3.php:
<?php
if(!empty($_POST['user'])){
echo 'post: '.$_POST['user'];
}
else{
echo 'nope post3.';
}
?>
When using a form on post1.php, I could get post3.php to echo 'nope post3.' which shows that post values don't stick around after a redirect. However, when using the current version of post1.php, I could only get post2.php to echo 'nope post2.', meaning that setting $_POST variables manually doesn't work, or I could on the validation page enter $_POST['var']=$_POST['var'] and it would save the post variable through one more redirect.
I know this could be done using SESSION variables, but I feel like that could get messy quickly.
and before you comment about security risks, I obviously wouldn't do this with any sensitive information.
tl:dr; How do I best send variables back to the page the form is on after form validation fails?

I think as you mention using $_SESSION is more appropriate in this case. When You put something like:
$_SESSION['formVariables'] = $_POST;
then You can refer to these variables when you will be back on form1.php page.
The best solution would be to do validation on same page as the form by including validation script before the form and then if all is correct redirect to relevant page.
Is there any particular reson why you want to do validation on different page than form?

Related

php $_POST variable is not saving

I currently have some php code on a form action, and it is being updated to the form's next page with
<?php echo $_POST['var here']; ?>
and it is working, but I noticed when Im trying to refresh the page it asks to confirm resubmission. When I resubmit it works in that tab in which it was sumbitted, but in another new tab it does not show the displayed php post variables. I even took it the next step by seeing that when I open the 2nd page after the form action has been submitted the php post variables are gone...
Help!
Thanks!
When you submit a form with <form method="post" /> it does a post request to the server, thus populating $_POST. When you open the link in a new tab it is no longer a post request but a get request. That is why you'll see nothing in $_POST.
$_POST — usually from forms
$_GET - from values on the URL (the query string myscript.php?myvar=Joe)
You can find plenty of resource about it. You can start here
If you want to keep the values you can save them to the session:
<?php
session_start(); // should be at the top of your php
if (isset($_POST['var'])) {
$_SESSION['var'] = $_POST['var'];
}
$myvar = isset($_SESSION['var']) ? $_SESSION['var'] : "no var";
echo $myvar;
Now the value is stored in the session so you can visit the page in a new tab and it will still be there.
This sounds like desired behavior. The $_POST variable should only be filled when the post action is created. If you're looking to store variables across pages you could store it in either the $_SESSION var in PHP or deal with the front end $_COOKIE business. If you're always going to be rendering pages from the backend then $_SESSION is the way to go. It's never too late to read up on cookies and sessions.
The skinny of it is that you're going to want to do something like this:
<?php
session_start();
if ($_POST['var']) {
$_SESSION['var'] = $_POST['var'];
}
echo $_SESSION['var'] ?: $defaultValue;
Then you'll notice that the message changes only when you post and won't exist before then.

How to Validate a form in within the same page and when there are no errors send it to another page for further registration?

Okay. I have yet another easy problem which I can't solve. I am working with PHP and I am working on a form to be validated by PHP. I have validated the form in another page containing the same elements. That's the
<form name = "Order Form" action = "<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method = "post">
but now the problem arises is that, when we have validated the form and there are no more errors, how to send the data for further registration in other pages. Assuming that Javascript is off I have to use this method. Help is very much appreciated.
You can use session to store some data for a short time such as registration process example:
<?php session_start();
if(noerror){
$_SESSION['username']=$username;
//similarly do for more
header("Location:next_page.php");
}
else{
//show error
}
Note: Alternatively You can also use hidden input but I will discourage that as for security purpose you need to re-validate that.
Update:
To check if an error has occurred or not no need to count them simply use an variable called $noerror and initialize it with TRUE and as soon as an error occurs set it to false then simply put it in if($noerror) at last.
If you want to display error message store them in an array like $error_log
example:
if(error_in_username){
$noerror=false;
$error_log['username']="Invalid Username";
}
Please refer to below link.
http://www.w3schools.com/php/php_form_url_email.asp
Hope this will solve your problem.
On your validation 'page' which should be a controller of sorts, if validation is successful, load the step2 page with the previous form data in hidden inputs.
OR
After successful validation of step1, save the data already into database (could be a temp table), and then proceed to step2 with the id of the entry you just saved. On submission of step2, you can merge the step2 data with the data of the entry that was saved in the database, and proceed to step3 if necessary. etc.
If you simply want to get to another page, the basic logic is:
if(validation_success)
{
header("Location: step2.php");
} else {
show_errors();
}

how to assign post globals on a redirected page?

I have a login form which sends 3 post values from username, password and submit button. But my form processor has 3 pages one is validation.php which validates the field second is read.php which checks the posted values against db and third is login.php which is a result of login success. All redirect to each other respectively on success. Problem here is that when I try to access the user posted values from form in read.php (redirected page) not validate.php (action page) I get an error of undefined index.
I really don't see why you are doing all those redirects, but if you want to make the data more persistent you could use a session variable, because the $_POST superglobal is only set for the current request.
firstfile.php
<?php
session_start();
$_SESSION['posted_data'] = $_POST;
other file
<?php
session_start();
var_dump($_SESSION['posted_data']);
However as already stated you may really want to reconsider doing all the requests.
UPDATE
Besides the fact that you will loose your data you are also doing multiple (unneeded) requests to simply sumbit the form. The only redirect that should happen is to the successpage when you have done all you work. See this for more information: http://en.wikipedia.org/wiki/Post/Redirect/Get
If you are look to keep you code clean you could always just include the other files or go for an OOP approach.
You should do one page only that will do all the work. That doesn't seem too complicated of a script, so I would advise putting everthing together on one page.
You did not provide any code so I'll show you a general example. I just typed it without rereading so it's not pure PHP syntax, just the spirit:
<?php
$login=$_POST['login'];
$pwd=$_POST['pwd'];
$dbcheck = mysql_fetch_array(mysql_query("SELECT COUNT(1) FROM table WHERE user =$login and pwd = $pwd"))
if($dbcheck[0] > 0) {
//Login success
//Setup your session variables, cookies, etc
//Then you can do your redirect here
} else {
//Page for wrong login
}

I am confused about PHP Post/Redirect/Get

In an article on preventing PHP form resubmissions, I read the following:
(Not quoting) This could be the page that receives the form data, for example called "form.php":
<form action="submit.php">
<input type="text" name="user" required />
<input type="password" name="pass" required />
<input type="submit" value="Log in" />
</form>
The page that would process the POST data would therefore be called "submit.php". If the login went correctly, this code would run:
header('Location: /login/form.php?success=true');
However, couldn't a user just navigate to the URL above? Also, what is the purpose of the GET variable? Couldn't I just have a script at form.php that checks if the user is logged in?
At submit.php, should I save the logged in username as $_SESSION['username'], and then check if isset() at form.php? Also, since a URL with "success" in it isn't really pretty, is it economical to redirect the user once again? Should I use PHP header() or Javascript window.location.href? As you see, I'm sort of confused.
Thanks for any help.
However, couldn't a user just navigate to the URL above?
Yes, he can. This will not cause anything bad though.
Also, what is the purpose of the GET variable?
To have some flag that represents the fact that the form has been processed successfully and you need to congratulate user.
Couldn't I just have a script at form.php that checks if the user is logged in?
Uhm, you can keep your code in the way you like. There is no any strong requirements
At submit.php, should I save the logged in username as $_SESSION['username'], and then check if isset() at form.php?
If you need to persist it across the current session - yes, do so.
Also, since a URL with "success" in it isn't really pretty, is it economical to redirect the user once again?
Redirect where. Redirection is pretty cheap thing.
Should I use PHP header() or Javascript window.location.href?
You definitely should do that in php, otherwise you'll get the troubles you're trying to avoid following PRG-way.
PRG or Post/Redirect/Get is just a pattern you can use to prevent the message boxes. How you use it in detail (and the article does only a generic suggestion) depends on your needs.
If you want to flag the success flash message inside a cookie or a session or a get variable, that's totally up to you. A second redirect won't help btw, you'll learn that if you play around with it.
The only important part is, that after you have received the POST request, you do the redirect. The user then can still move back and forward in history w/o being asked to re-submit POST data.
The pattern works and is a fine thing. Just two days ago I did it again and a step-by-step weppapp installer was much nicer to navigate with the browser interface.
About your redirect
This code is wrong:
header('Location:/login/form.php?success=true');
First of all, you need to have a space after the colon:
header('Location: /login/form.php?success=true');
Then the address must be an absolute URI, it must contain the full URL:
header('Location: http://example.com/login/form.php?success=true');
Next to the header(), you should provide a message body as per RFC, many so called "web-developers" don't even know:
$url = 'http://example.com/login/form.php?success=true';
header(sprintf('Location: %s', $url));
printf('Moved.', $url);
exit;
Don't forget the exit. Sure, that's pretty much re-enventing the wheel, instead install the http extension of PHP and just do this line:
http_redirect('/login/form.php?success=true');
You find that nifty helper here.
To recap: Important is that you do the redirect after post. Everything else, like passing a variable is totally up to you how you would like to do it.
Yes, you should never rely on a GET variable (or even a hidden POST variable) to say, "sure, let me in, I'm a valid user!".
Personally, I would strip the GET information from the link and rely solely on session variables. Remember to place a 'session_start();' as the first line of code if you are using PHP to activate the session.
For submit.php:
<?php
session_start();
if ($_POST['user'] && $_POST['pass']) { // Make sure both variable are set
if (your_method) {
// Code to check if the user and pass are valid however you plan
$_SESSION['user'] = $_POST['user'];
$_SESSION['loggedin'] = time();
}
}
header('Location: form.php'); // Either way, pass or fail, return to form.php
exit();
?>
Then in form.php:
<?php
session_start();
$activeuser = false;
if ($_SESSION['user'] && $_SESSION['loggedin'] < (time()+600)) {
// Check if the user exists and the last access was with in 10 minutes.
$_SESSION['loggedin'] = time(); // If so, keep them up to date!
$activeuser = true;
}
if ($activeuser) {
// whatever should show to someone logged in
} else {
// Show log in form
}
?>
Also, you may already know this, but the default method of transferring is GET, so be sure to specify method="post" in the form tag.
It's normally best to use header() to redirect if needed as Javascript is client-side and can be avoided which can break your intent for the functioning of your site.
The main idea behind POST/REDIRECT/GET, as the article you linked to points out, is to avoid users resubmitting data (most of the time). Generally, you don't want the same POST (with the exact same data) to happen twice -- indeed, in some situations, it could end up performing some action (like charging a credit card) a second time, which would be bad.
Most of what you ask about in your question are implementation details (like sending the ?success request parameter in the redirect).
In practice, what usually happens is that your redirect on success. If, for example, the user's input fails validation, you don't redirect, and instead, redisplay the form, along with relevant error messages.
Here's a basic example, all in one script. I've tried to include only what's important, with as little extraneous stuff as possible.
login.php
<?php
/**
* ensure user supplied both username & password
* #return mixed true or an array of error messages
*/
function validate_login_values($vars){
$errors = array();
if (empty($vars['username'])) $errors[] = 'You must supply a username, genius.';
if (empty($vars['password'])) $errors[] = 'You must supply a password, dummy.';
if (empty($errors)) return true;
return $errors; // $errors must be an array.
}
if (! empty($_POST)){
$validationResults = validate_login_values($_POST);
if ($validationResults === true){
// assume here that authenticate properly escapes it's arguments before sending them
// to the database.
if (authenticate($_POST['username'],$_POST['password'])){
//GREAT SUCCESS! The user is now logged in. Redirect to home page
header("Location: /");
die();
}
$errors[] = 'Invalid username/password. Try again, slim";
}else{
$errors = $validationResults; // validate_login_values created errors.
}
}
?>
<h1>Log In, Friend!</h1>]
<?php
//display errors, if there were any
if (! empty($errors)): ?>
<div class="errors">Something went horribly wrong:
<ul><?php foreach($errors as $e) echo "<li>$e</li>"; ?></ul>
<div>
<?php endif; ?>
<form method="POST">
<!-- //username, password, and submit -->
</form>

Form validation losing variables

Let's say I enter a registration form with this ending URL: registration.php?accountType=a
The form is parsed on the same page (registration.php). If the user doesn't pass form validation they are taken to registration.php with error messages. So you see I lost my variable accountType=a. My question:
Can I submit a form for validation and retain the accountType variable? I'm aware that this could easily be done using a cookie. I just want a further understanding.
Solution: Although all of the answers below were valid, I went with a Session variable and <form action="registration.php?<?php print 'accountType=' . $_SESSION['accountType']; ?>" etc. Thanks for the help.
You should use this in your form:
<form action="registration.php?accountType=a">
You should use this in your php:
if ($validation_success) {
header('sucess.php')
} else {
// don't do anything. The page(registration.php?accountType=a) loads
}
I'm just giving you the idea.
You can easily to it in 3 ways...
Using PHP Sessions. Simply do something like
session_start();
$_SESSION['namespace'] = array('post' => $_POST, 'get' => $_GET);
Using Cookie (Session seems for me to be more elegant).
Use Ajax request; it will make your tasks easier.
I think you should add the "accountType=$accountType" at the url's end, when you make a http forward, so the user will taken back to the correct page.
I dont see your code, but maybe like this:
if(auth())
{
//do something...
}
else
{
header("Location: /registration.php?somerror=true&accountType=" . $accountType);
}

Categories