I am trying to redirect a user to a 'success' page if the registration was successful. However, by this point, headers have already been sent so I can't just call header() directly.
What I did instead was put an included file (call it redirect.php) above the Doctype on the page:
// handle requested redirects
if (isset($_POST['redirect_to']))
{
$new_page = $_POST['redirect_to'];
header("Location: http://localhost/$new_page");
}
So if $_POST['redirect_to'] is set, then header() can redirect to that page. Now the problem with this approach is that this $_POST[''] variable is inside a function tasked with processing the user's registration, so of course, the form has already been submitted before the post variable is set, and therefore, redirect.php never gets to see the post variable.
Is there an easy way around this or am I making this harder than it needs to be?
Since you havent mentioned AJAX my guess is that you are just having a wrong concept of registration process.
Common registration process and structure:
<?php
if( !empty($_POST['registerme']) ){
// do the registration process and possible errors STORE IN THE VARIABLE
// lets say $errors, it could be an array of strings or anything you want
// if registration process was succesfull,
// set $reg_suc to true otherwise to false
if( $reg_suc ){
header('Location: success.php');
exit();
}
}
?>
<?php
if( !empty($errors) ){
//there were some errors
foreach( $errors as $error ) echo $error."<br>\n";
}
?>
<form action="#" method="POST">
<input type="hidden" name="registerme" value="registerme">
<input type="text" name="validateName" placeholder="name">
<?php if( !empty($errors['validateName']) ) echo "Please correct this value"; ?>
<!--
//some more input fields
-->
<input type="submit" value="Register">
</form>
EDIT: This is of course common only for very simple applications with registration/login functionality, in MVC(P) architecture and similar achitectures this is usually created by a view using template file providing HTML template and a model/controller or model/presenter (in e.g. PHP) that are handling the registration/login process and possible error log and that are outputting results, errors and other data through the view back to user...
Related
I learned this back in college a few years ago, and now I actually have to do something like this for work. I'm sifting through my old homework assignments and man I wish I was neater.
I'm creating a registration page.
User submits POST to self -> php validates on the same page
if it's good
I direct to a thankYou.php page and clear any variables.
if it's no good, I redirect to myself and populate the form with my bad answers.
Do i need to start a session and store all my variables in a session or something?
I omitted some of the code. to make it quicker to read
<?php
//connect to database.....
//Extracting the data
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$pageValid = true;
$fName = $_POST['fName'];
$lName = $_POST['lName'];
};
//validate $fname $lname etc $pageValid = true if it's all good
if ($_SERVER['REQUEST_METHOD'] == 'POST'){
if ($pageValid == true){
//insert into sql
header('Location: thankyou.php');
exit;
} else {
//if page is not valid redirect come back here
header('Location: register.php');
exit;
};
} //<!--End of ($_SERVER['REQUEST_METHOD'] == 'POST')
?>
<!DOCTYPE html>
<html lang="en">
<head>header...</head>
<body>
<div id="form" class="col-md-12">
<form id="form1" name="form1" method="post" action="<?php $_SERVER['PHP_SELF']; ?>">
<table class="table"><tr>
<td width="200"><label for="firstName">First Name:</label></td>
<td>
<input name="fName" type="text" id="register"
value="<?php
//$fName I want to add the value of $fName here after it gets redirected
?>" size="25" maxlength="50" /> *
<?php print $fNameError;?>
</td>
</tr>
</table>
</body>
</html>
fName can be populated with $_REQUEST['fName']
You could always retrieve the value of every post inputs using $_POST (or $_GET for forms with the GET method)
In both cases, you can retrieve your input values accessing the array $_REQUEST. Find here the documentation
Using a session is a really really bad idea: it would cause you tons of headache when your user will start accessing your web app from multiple tabs. It is also a problem since it will require you to clear the session after having processed the form, or unexpected results may happen the next time the user will use the form (like, for example, input fields automatically and unexplainably filled with no user input).
Update
Storing forms inputs in the session is discouraged for at least two reasons:
sessions are shared between all the pages concurrently opened by the same user. Imagine you open the form in a tab and you submit it with some errors; the web app will re-open the form, filling the forms with the data it has in session. Now, open a second tab with the same form: the session is still the same, so the form will be filled with the data in the first form. Submit it with some errors: you will have changed the data for both the forms
$_REQUEST items are populated during a POST, and they are automatically cleaned up the next request; sessions are not, they are persisted for the whole session. This means that your code will need to clear them up explicitely, or you will risk to find form inputs with the old values even without a form submit
Yes, storing data in $_SESSION variable is a good idea.
e.g.$_SESSION["lname"] = $_POST["lname"];. Obvioulsy you need to start a session, check for input validity, etc....
Basically you check for the existence of a POST variable:
<?php
if( isset( $_POST['fName'] ) )
{
// the form has been submitted, do something
}
?>
You don't have to use session variables if your form data is displayed on the page that receives the POST data.
Edit
If you want to populate some $_SESSION variables then you could stuff all the POST data into a session array
<?php
if( isset( $_POST['fName'] ) )
{
$_SESSION['posted'] = $_POST;
}
?>
Or, if you validate POST data and want to populate the session with only valid input:
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$_SESSION['formData'] = array();
$_SESSION['formData']['pageValid'] = true;
$_SESSION['formData']['fName'] = $_POST['fName'];
$_SESSION['formData']['lName'] = $_POST['lName'];
};
?>
You don't need to redirect back to the form on an error... The form is built within the same script so just let it render the rest of the script. You only need a redirect on valid registration data.
Basically, get rid of the "else" portion of you PHP.
If I have a php contact form with session_start() at the top, I know this creates a session. But what if the user doesn't fill out the form and instead navigates to a different page?
Do I still need to use session_destroy since I only want a session created when a user submits a php form via my contact page?
Thanks.
UPDATE: For a better idea on my form without posting lengthy code.
contact-form.html
<?php session_start(); ?>
<?php $fname = isset($_SESSION['fname'] ) ? $_SESSION['fname'] : NULL ; ?>
<form method="post" action="http://www.mysite.com/form-process.php">
<input value="<?php echo $fname ?>" type="text" id="fname" name="fname" />
<input type="submit" value="Submit Request" />
</form>
form-process.php
<?php
session_start();
$_SESSION['fname'] = $_POST['fname'];
$user = "John" ;
session_write_close();
if ($_SESSION['fname'] != $user) {
header('Location: http://www.mysite.com/contact-form.html');
}
else {
$_SESSION = array();
session_destroy();
header('Location: http://www.mysite.com/thankyou.html');
}
?>
The overhead of creating a session is miniscule, there's no real reason you'd need to session_destroy() though you could put the session_start() in the block that detects post rather than at the top of the script if you only want to use the session when the user posts.
If you only want a session created when the user submits certain form, just do it as you describe. It's not mandatory to put session_start() on every page of the site and it doesn't need to be the first line in the file (it just needs to be able to generate a cookie, thus it needs to be before any output).
// contact-form.php
if( $_SERVER['REQUEST_METHOD']=='POST' ){
session_start();
// ...
}
The stateless nature of HTTP makes it impossible to actively remove a session if the user hasn't completed certain task. But if you don't load session on other parts of the site, the session file will be removed on next garbage collection after its expiration time, even if the user is still browsing your site. Other than that, a session is just a tiny text file lying harmlessly on a temporary directory.
In PHP I want to use a script held in a separate file to process a form and validate it. If there are errors I want the form to display the errors and original values for the user to change.
At the moment the validation script is on the same page as the form and all works ok. However I would like this away from the form and send the form variables to the script using the 'action' in the form.
If I do this though, how can I then go back to the form with error messages and original values — do I simply use $_POST in the script and a header location? or is there a better method.
If the form validates okay I'll then go to a separate page (using a header).
Can anyone help me understand the process/logic I should be trying to achieve and the function s to past variables between the pages ($_GET?)
If you want to track variables across multiple pages, it might be feasible to investigate sessions. You can assign variables from $_GET or $_POST to the session, and they will be accessible across pages.
I think what you are looking for is a framework called Model-View-Controller (MVC). In your case, your form is the "view" and script to process data is "controller" then the controller has the option what to show to the user (view) which is your form with error message or some other page with success message. But MVC is a bit more complex than that. If you want to study MVC, read some articles and choose MVC framework to use like CakePHP, CodeIgniter, Zend framework et cetera.
If you are studying basics of PHP, you might not want to start using a framework, in that case, you can do something like this (login sample):
login.php
<?php
$error = "";
$username = "";
$password = "";
//POST method used. The user is trying to login
if(isset($_POST))
{
$username = $_POST["username"];
$password = $_POST["password"];
//process login here
//check database
if($success == true)
{
header( 'Location: home.php' ) ;
}
else
{
include "login-view.php";
$error = "Either username or password is incorrect.";
}
}
else //GET method used. The user visits the login page
{
include "login-view.php";
}
?>
login-view.php
<p><?php echo $error; ?></p>
<form method="post" action="login.php">
<input type="text" name="username" value="<?php echo $username ?>" />
<input type="password" name="password" />
<input type="submit" value="send" />
</form>
The code above goes like this:
1) The user visit the login page. login.php will detect that the method used is GET -- cliocking a link, opening a bookmark or typing URL to address bar. login.php then will include login-view which contains the form.
2) The user type his username and password and click submit button. login.php will detect that the request is POST, then validate username and password, provide error message if necessary. If valid, then redirect to home page, if not, include login-view.php (form), this time with error message and previously typed username.
How can process a form on the same page vs using a separate process page. Right now for signups, comment submissions, etc I use a second page that verifies data and then submits and routes back to home.php. How can I make it so that on submit, the page itself verifies rather than using a second page.
You can tell the form to submit to the PHP's self, then check the $_POST variables for form processing. This method is very good for error checking as you can set an error and then have the form reload with any information the user's previously submitted still in tact (i.e. they don't lose their submission).
When the "submit" button is clicked, it will POST the information to the same page, running the PHP code at the top. If an error occurs (based on your checks), the form will reload for the user with the errors displayed and any information the user supplied still in the fields. If an error doesn't occur, you will display a confirmation page instead of the form.
<?php
//Form submitted
if(isset($_POST['submit'])) {
//Error checking
if(!$_POST['yourname']) {
$error['yourname'] = "<p>Please supply your name.</p>\n";
}
if(!$_POST['address']) {
$error['address'] = "<p>Please supply your address.</p>\n";
}
//No errors, process
if(!is_array($error)) {
//Process your form
//Display confirmation page
echo "<p>Thank you for your submission.</p>\n";
//Require or include any page footer you might have
//here as well so the style of your page isn't broken.
//Then exit the script.
exit;
}
}
?>
<form method="post" action="<?=$_SERVER['PHP_SELF']?>">
<?=$error['yourname']?>
<p><label for="yourname">Your Name:</label><input type="text" id="yourname" name="yourname" value="<?=($_POST['yourname'] ? htmlentities($_POST['yourname']) : '')?>" /></p>
<?=$error['address']?>
<p><label for="address">Your Address:</label><input type="text" id="address" name="address" value="<?=($_POST['address'] ? htmlentities($_POST['address']) : '')?>" /></p>
<p><input type="submit" name="submit" value="Submit" /></p>
</form>
The easiest construction is to detect whether the $_POST array is not empty
if(isset($_POST['myVarInTheForm'])) {
// Process the form
}
// do the regular job
you can check if it was POST request inside the page's code and then check the data. If it was GET request - just show the form.
But please remember that is is a good practice to show successfull form submission results on a different page served through GET request, i.e. any successfull form POST should be answered with redirect to the success page.
You could of course explore looking into AJAX requests, where you would make an asynchronous call to your handler script, and then update then update the sending page with a success message. This gives the impression of "Same page processing" i.e. The page doesn't have to refresh.
It really depends on the effect you are trying to achieve however.
#Michael Irigoyen: It works fine, but on first rn/load, it shows:
"Notice: Undefined variable: error in C:\xampp\htdocs\same_page.php on line 28"
How to handle this notice?
Got it now:
"Used isset, # etc. to supress errors..."
"Works like a charm!!!"
"Now i'll try it on my code..."
I have saved a thank you message and refreshed using session variables.
if(!is_array($error)){
$_SESSION['message'] = 'Thank You!';
header('Location: yourpage.php');
exit();
}
and then use this in the top of the form:
if(isset($_SESSION['message'])){
echo $_SESSION['message'];
unset($_SESSION['message'];
}
This should refresh the page and show the message and then if they refresh the page the session variable is empty so the thank you won't show. This is called a flash message.
I have a basic PHP form page that contains quite a large amount of data that will be saved into about 4-5 different tables in MySql once it is all done. Since constructing this save routine will take a bit of PHP I'm looking to have the POST action to not point at PHP_SELF and instead a separate PHP file for processing.
Where all general data such as phone numbers, email, zip codes, etc. will be validated prior to the submit is passed to the processor script, if an error is returned by the processor...
What is the best practice way to point back to the original form page (HTTP_REFERER) while maintaining data input?
Form page:
<form action="processor.php" action="post">
<!-- lots of fields -->
<input type="submit" id="submitButton" name="Save" value="Save" />
</form>
Processor page:
<?php
if ( isset($_POST['date']) && ($_SERVER['HTTP_REFERER'] == "form.php") )
{
$errors = false;
//attempt to put data in database
if ( $errors )
{
//Pass back to the form.php page with error message and all data intact
}
}
?>
I have come across this problem before, how we solved this was to put all the fields into a session, then redirect back to form.php using header("Location: form.php");
When the data was posted to the form, we stored the $_REQUEST into a $_SESSION['post']; if the validation failed, we sent it back to the form, populated the fields and unset the session.
So for example
$_SESSION['post']['field_a'] = $_REQUEST['field_a'];
$_SESSION['post']['field_b'] = $_REQUEST['field_b'];
With some fancy naming conventions you can just loop this to make it easy.
Then on the Form page, we just checked to see if there was some data, or just echo the data regardless.
$str_field_a = #$_SESSION['post']['field_a'];
...
<input name="field_a" value="<?php echo $str_field_a; ?>" />
...
unset($_SESSION['post']);
This is probably a messy way of doing this, but it has proven effective for our purposes. Just thought I'd share.
I would send a post back to form.php containing errors and values. I use the same method in my personal project.
if ( $errors ) {
?><form action="form.php" method="post" name="error">
<input type="hidden" name="errcode" value="<?php echo $errorcodes; /*or whatever message*/ ?>" />
<input type="hidden" name="anotherdata" value="anothervalue" />
<?php /*you can add all post datas here as hidden field*/ ?>
</form>
<script type="text/javascript">document.error.submit();</script><?php
}
And this is similar to my form.php
//first I set default blank variables for form
$formvalue="";
$formnumericvalue="";
//i set them, yay!
//if I get values from post.php, I update the values
if (isset($_POST['iserror'])) { //you can either echo a error message or update current data here, I'm showing this for both
$formvalue=$_POST['formvalue'];//don't forget to validate these!
$formnumericvalue=$_POST['formnumericvalue']; //don't forget to validate these!
}
//I also do this method for edit forms
//and finally I show the form
?>
<form name="form" method="post" action="post.php">
<input type="text" name="formvalue" value="<?php echo $formvalue; ?>" />
</form>
I think you can do that using an array of error.
Set error flag false (if error occurs then set it true and so not store in database).
Check element 1, if error then store it in array $error['name'] = 'value'
Similarly check all elements, and store using same procedure.
In the end if error flag is set to false do not store in database and (if on the same page, you will be able to access the array on form where you want to display error message. )
if(isset($error['elementname'])) echo $error['elementname'];
below the page.
However, the best approach is to use an Object Oriented approach.
[UPDATE]
storing php objects on html form element and passing php objects through GET method?
how to send redirect page pass variables as post variables from a php script
Also I guess, storing the whole object in SESSION would not be a bad approach