I have found many sites that describes PRG, but no simple PHP code example.
Here's what I implemented:
The form.php has an action: validate.php.
The validate.php is never seen by the user; if validates all $_GET and, if valid writes it to database and generates the HTML of a confirmation page / if not valid, it generates the HTML of an error page explaining what is wrong.
Whichever HTML is generated get stored in a $_SESSION variable and then validate.php calls header('Location: <as appropriate>);.
The submitted.php of invalid_input.php (in case the user reads the URL) consists only of echo $_SESSION['form_html'];.
That seems to me like protection against both page reload and back button problems.
Did I goof by trying to reinvent the wheel?
Simplest scenario:
<?php
if ($_POST) {
//validate the input
if (/* input is OK */) {
// Execute code (such as database updates) here.
// Redirect to this page.
header( "Location: {$_SERVER['REQUEST_URI']}", true, 303 );
exit();
}
}
?>
<html>
<!-- here goes your HTML page with a form -->
Use REQUEST_URI. Do not use PHP_SELF as in most CMS systems and frameworks PHP_SELF would refer to /index.php.
A snippet of code:
if (count($_POST)) {
// process the POST data
// your code here- so for example to log a user in, register a new account..
// ...make a payment...etc
// redirect to the same page without the POST data, including any GET info you
// want, you could add a clause to detect whether processing the post data has
// been successful or not, depending on your needs
$get_info = "?status=success";
// if not using rewrite
// header("Location: ".$_SERVER['PHP_SELF'].$get_info);
// if using apache rewrite
header("Location: ".$_SERVER['REQUEST_URI'].$get_info);
exit();
}
Browser
HTML form
method=POST
|
v
PHP app
reads $_POST
sends 303 header
|
v
Browser
receives header
redirected to
new page
|
v
PHP app
reads $_GET
does whatever
A common use is in login authentication. That's the process flow when user submits the login form. PHP app authenticates user via $_POST vars. Sends a 303 header back to browser when the user has successfully authenticated. So user is redirected to a new page.
I would like to introduce you to a method that is often used on a greater scale and in much more detail in frameworks.
What we are going to do
We have a file called index.php.
We are going to submit a form
We are going to check for this submit
We will add the POST data to a session
We will redirect the user to a confirmation page
We will display the data and let the user confirm.
We will submit, and finally process the data.
We will redirect back to index.php and show a notification.
The code
<?php
if (!isset($_SESSION)) session_start();
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
switch ($_POST['submit']) {
case 'add':
// This is where our first POST will end up
// We can perform actions such as checking the data here
// After that we will add the POST data to a session
$_SESSION['postdata'] = $_POST;
// and unset the $_POST afterwards, to prevent refreshes from resubmitting.
unset($_POST);
// Now we will redirect...
header("Location: ".$_SERVER['PHP_SELF']);
break;
case 'confirm':
// We can now insert the data into the database or email it
// Then we will unset the session and redirect back
unset($_SESSION['postdata']);
// This is to display our notification
$_SESSION['success'] = true;
// And there we go again...
header("Location: ".$_SERVER['PHP_SELF']);
break;
}
// We will exit here because we don't want the script to execute any further.
exit;
}
?>
<?php if (isset($_SESSION['success']) && $_SESSION['success'] == true): ?>
<p>Our data has been processed succesfully</p>
<?php unset($_SESSION['success']); ?>
<?php endif; ?>
<?php if (isset($_SESSION['postdata'])): ?>
<p>
You want to add the following data:<br />
<pre><?php print_r($_SESSION['postdata']); ?></pre>
Is this correct?<br />
<form method="POST" action="<?= $_SERVER['PHP_SELF']; ?>">
<button type="submit" name="submit" value="confirm">Yes</button>
</form>
</p>
<?php else: ?>
<p>
<form method="POST" action="<?= $_SERVER['PHP_SELF']; ?>">
<input type="text" name="..."><br />
<input type="text" name="..."><br />
<input type="text" name="..."><br />
<input type="text" name="..."><br />
<button type="submit" name="submit" value="add">Add something</button>
</form>
</p>
<?php endif; ?>
Here is form.php
<?php
session_start();
// 1) _____________________________________________ POST _____________________________
if ( count($_POST) ) {
$ermsg ='';
…
check data, write some data to database(s), set error message(s) if any
…
$userdata1 = $_POST['htUserdata1'];
$userdata2 = $_POST['htUserdata2'];
…
$_SESSION['PRG'] = array('field1'=>$userdata1,'field2'=>$userdata1,…,'ermsg'=>$ermsg);
session_write_close();
header('Location: ' . $_SERVER['REQUEST_URI'].'?z',true,303);
exit;
// 2) _____________________________________________ REDIRECT ________________________
} else if ( array_key_exists('PRG',$_SESSION) ) {
$userdata1 = $_SESSION['PRG']['field1'];
$userdata2 = $_SESSION['PRG']['field2'];
…
$ermsg = $_SESSION['PRG']['ermsg'];
unset($_SESSION['PRG']);
// 3) _____________________________________________ GET ______________________________
} else {
…
retrieve data from database(s)
…
$userdata1 = dbGet1();
$userdata2 = dbGet2();
…
$ermsg = '';
}
// 4) _____________________________________________ DISPLAY _________________________
?>
<!DOCTYPE html>
<html lang="fr">
…
<form method="post" action="form.php" accept-charset="utf-8">
<input id="htUserdata1" name="htUserdata1" type="text"/>
<input id="htUserdata2" name="htUserdata2" type="text"/>
…
</form>
<script language="javascript">
"use strict";
<?php
$G['htUserdata1'] = $userdata1;
$G['htUserdata2'] = $userdata2;
…
$G['ermsg'] = $ermsg;
$myJSON = json_encode($G);
echo "var G=$myJSON;";
?>
document.getElementById('htUserdata1').value = G.htUserdata1;
document.getElementById('htUserdata2').value = G.htUserdata2;
…
if ( G.ermsg !=='') alert(G.ermsg);
</script></body></html>
Caller.htm
<form method="post" action="Callee.php?Query1">
<input type="text" name="PostData" />
<input type="submit" value="Go" />
</form>
Callee.php (Is called twice.)
if ($_POST) {
header("Location: ". $_SERVER['REQUEST_URI']. 'Query2');
// PART1: Use $_POST and $_GET to execute database updates here...
// Now any display (i.e. echo or print) will come after the header.
// ...
die; // When done, GET 'myself' to execute PART2 below.
}
// PART2: Results page goes here...
echo 'PART 2 display output: '; var_dump($_GET);
Notice there are two query strings involved
Look what var_dump says about $_GET:
PART 2 display output: array(1) { ["Query1Query2"]=> string(0) "" }
Issues with putting header at the end of the POST section like this:
header("Location: ". $_SERVER['REQUEST_URI']. 'Query2'); die;
The php manual says: "Remember that header() must be called before any actual output is sent, either by normal HTML tags, blank lines in a file, or from PHP. It is a very common error to read code with include, or require, functions, or another file access function, and have spaces or empty lines that are output before header() is called. The same problem exists when using a single PHP/HTML file."
However if you need to build 'Query2' based on what happens in the POST section, it may need to be at the bottom of the POST section. This is ok, so long as you don't try to insert any echo's above it, not even for testing.
Related
I work in PHP. I want to redirect page after login to the last page that i want to visit, but I'm still stack at here in 5 hours and I still don't make it yet. This is the schema, I have 3 php file.
newest.php (before login),
signin.php (before login),
thread.php (after login).
I'm using cookies for this redirecting. First i went to the newest.php, then i clicked the button (go to thread.php). Then thread.php saw that you haven't loggin yet, then redirected to signin.php. After i fill the signin form then, i clicked the submit button (the signin.php), then I'm stack at signin.php (not going anywhere) even after I've loggin in, it should be go to thread.php automatically.
this is my code in newest.php & thread.php (not in signin.php):
$coopage='coopage';
$current_page='http://'.$_SERVER[HTTP_HOST].$_SERVER[REQUEST_URI];
setcookie($coopage, $current_page,time()+86400,'/');
submit button in newest.php (it goes to thread.php):
echo "<center><button onclick=\"window.location='/thread/form'\">add new thread</button></center>";
in signin.php (after i clicked the submit button or in submit area, because form and after submit i made in the same page) (in the bottom of the page):
if(isset($_COOKIE[$coopage])){
$url=$_COOKIE[$coopage];
unset($_COOKIE[$coopage]);
header('location:'.$url);
}
note: in signin.php i also have another cookie setup before this cookie, is that the cause of this? or does it matter if i have 2 cookies setup in one page? Another cookie setup is like this (at the top of the page)
$cooval2='juna';
setcookie($coousername, $cooval2, time() + (3600 * 24 * 365), "/"); // 1 year
I would not use cookies at all.
Method 1
A possible way could be to store the link visited into a session variable and then when the user reaches the login.php page, provide a header redirect to $url given by the session variable.
Paste this code into all your pages on your website or the main container.
<?php
session_start();
$_SESSION['url'] = $_SERVER['REQUEST_URI'];
For the login page you can have:
<?php
session_start(); // needed for sessions.
if(isset($_SESSION['url']))
$url = $_SESSION['url']; // holds url for last page visited.
else
$url = "student_account.php";
header("Location: http://example.com/$url");
Method 2
A simpler solution by far is simply to have:
<hidden name="redirurl" value="<? echo $_SERVER['HTTP_REFERER']; ?>" />
Then redirect to that address once they log in.
However, this is only good if you have a login box on every page.
$_SERVER['REQUEST_URI'] will simply hold the current page. What you want to do is use $_SERVER['HTTP_REFERER'].
So save the HTTP_REFERER in a hidden element on your form, but also take note on that in the PHP that processes the form you will need some logic that redirects back to the login page if login fails but also to check that the referer is actually your website, if it isn't, then redirect back to the homepage.
Method 3
Another common way to do this is to pass the user's current page to the Login form via a $_GET variable.
change your script so that is also tells the login page to remember where you are:
Note: $_SERVER['REQUEST_URI'] is your current page
header("Location:login.php?location=" . urlencode($_SERVER['REQUEST_URI']));
Now check if it is populated, then send the user to this:
login.php
echo '<input type="hidden" name="location" value="';
if(isset($_GET['location'])) {
echo htmlspecialchars($_GET['location']);
}
echo '" />';
// Will show something like this:
// <input type="hidden" name="location" value="previousPage.php" />
login-check.php
session_start();
// our url is now stored as $_POST['location'] (posted from login.php). If it's blank, let's ignore it. Otherwise, let's do something with it.
$redirect = NULL;
if($_POST['location'] != '') {
$redirect = $_POST['location'];
}
if((empty($username) OR empty($password) AND !isset($_SESSION['id_login']))) {
$url = 'login.php?p=1';
// if we have a redirect URL, pass it back to login.php so we don't forget it
if(isset($redirect)) {
$url .= '&location=' . urlencode($redirect);
}
header("Location: " . $url);
exit();
}
elseif (!user_exists($username,$password) AND !isset($_SESSION['id_login'])) {
$url = 'login.php?p=2';
if(isset($redirect)) {
$url .= '&location=' . urlencode($redirect);
}
header("Location:" . $url);
exit();
}
elseif(isset($_SESSION['id_login'])) {
// if login is successful and there is a redirect address, send the user directly there
if($redirect)) {
header("Location:". $redirect);
} else {
header("Location:login.php?p=3");
}
exit();
}
Your new cookie => local storage, make sure to have this code on every page you what to log the url on except for the login page otherwise it will redirect you back to the login page.
var currentPage = window.location.href;
localStorage.lastPageVisited = currentPage
This is then the code for the submit button and it will redirect the user to the last page he visited.
$(document).ready(function() {
$('button').click(function() {
window.location.href = localStorage.lastPageVisited;
});
});
My question is may be foolish. But I want to know, if there is any code that prevent the page opening if tried with link but opens only after . if it's link is from another page.
for example, if i have a form on page contact.php and user gets redirected to page contact_success.php.
Now I want, if anybody tried to open contact_success.php page directly from browser address bar, it should not be get opened. It should be get opened only after form submission from contact.php page..
A simple way is just to use an if check on the contact_success.php page like
if($_SERVER['REQUEST_METHOD'] = "POST"){
//display page
} else {
echo 'You cannot view this page.';
//add redirect, if you like
}
Set a session or a cookie for the user in the contact.php, and then in the contact_sucess.php you can check if it exists.
for exmaple:
contact.php:
<?php
$_SESSION['visited_login'] = 'yes';
?>
contact_sucess.php:
<?php
if (isset($_SESSION['visited_login']) && $_SESSION['visited_login']=="yes") {
// output tanks
} else {
echo "go away";
die;
}
?>
You can use session for that example:
let say when you submit the contact form there is a page where in you will process the user input and i will use(refer to the #1)
contact_process.php
$_SESSION['success'] = 'success';
(this code will create a session)
then once success in processing the user input there is another page like(refer to # 2)
contact_success.php
if(isset($_SESSION['success'])
{
//Output if it is success
}
else{
header('location:contact.php');
}
(this code will check if session is existing if yes the desired output will show and if not it should turn back to contact.php)
you can easily learn session here http://www.w3schools.com/php/php_sessions.asp
please i need your help with an issue.
I have two forms on my homepage that i'll like users to fill and submit at different times. My problem is that i'll like to have only one processing page for both of them. Normally i can do this in seperate pages. But i'll like to know if doing it on the same page is possible.
Okay.. If i submit form A, on the action page, wont there be Undefined Index for variable of form B, that has not being submitted, and ofcourse using a GET is not adviced.
Thanks for your time and patience.
It's not completely unheard of to do this. Quite often, a different parameter is passed in the form element's action attribute like /submit.php?action=register or /submit.php?action=activate.
So, you have code like this:
if ($_GET['action'] == 'register') {
// Register user
} else if($_GET['action'] == 'activate' {
// Activate user
}
However, you could also just change the value of the submit button and have the action attribute the same for both forms:
if (isset($_POST['submit'])) {
if ($_POST['submit'] == 'register') {
// Register user
} else if($_POST['submit'] == 'activate') {
// Activate user
}
}
create separate form_process script then include in form pages.
if(!empty($_POST)){
include 'form_process.php';
}
form_process.php should contain only class/function without echo or print out.
alternately you may set action url to the same page then redirect back to proper page.
<form id="add-profile-form" action="form_controller.php" method="post">
<input type="hidden" name="act" value="adding"/>
<!-- form 1. -->
</form>
<form id="edit-profile-form" action="form_controller.php">
<input type="hidden" name="act" value="editing"/>
<!-- form 2. -->
</form>
form_controller.php
if(isset($_POST['act']){
if($_POST['act'] == 'adding'){
//process form1
}else if($_POST['act'] == 'editing'){
//process form2
}
header("Location: success.php");
}
You can do it on the same page also. Just you need to make action same for both the forms.
You need to make some condition and write the individual functionality for Form A and for Form B depending on the source form.
You can check with the parameters in action like #Ami has used.
/submit.php?action=register or /submit.php?action=activate
So, you have code like this:
if ($_GET['action'] == 'register') {
// Register user
} else if($_GET['action'] == 'activate' {
// Activate user
}
However, you could also just change the value of the submit button and have the action parameter the same for both forms:
if (isset($_POST['submit'])) {
if ($_POST['submit'] == 'register') {
// Register user
} else if($_POST['submit'] == 'activate') {
// Activate user
}
}
I have a simple input form on my site for people to enter in information for submission. The code looks like this in the case they do not enter anything:
this is form.php
if ($_POST['q']) == NULL ){
echo "Please enter your information"
The code works great, but it sends the user to form.php with the echo, where I want this to be echoed on my main page index.html right below the input box - basically so it doesn't navigate away from the page. Is this doable in php or will I need some javascript. I would have searched for ways to do this but I don't know what this method is called.
Thanks!
dont set a action in the url and it will submit to its self, if that still wont work you will need rewrite rules.
If you don't want to navigate away from the page you will need to use Javascript. Add a onSubmit to the form, and then let the function you call there return false, if the input is not complete and the form should not be submitted.
you can make it postback to itsself and then redirect the page to post.php?q=value if there is a value else echo below the input field.
<?php
$qisempty = false;
if(!empty($_POST['q']))
{
header("Location:http://../post.php?q=".$_POST['q']);
}
else
$qisempty = true;
?>
<input name="q" type="text">
<?php if($qisempty) echo "Please enter your information";?>
You can use AJAX for this thing. AJAX is great for this type of problems when you don't want to reload pages to do task in specific place or Div of HTMLpages.
For your problem, You need to create a HTML file with your form in it, and submit it via AJAX. and get your response via same AJAX.
<script type="text/javascript">
function submit_ajax(val1,val2,param1,param2,subfile){
var http = new XMLHttpRequest();
var url = subfile;
var params = val1+"="+param1+"&"+val2+"="+param2;
http.open("POST", url, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");
http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
//Remove the alert and use whatever you want to do with http.responsetext like
// document.getElementById("YourDiv").innerHTML=document.getElementById("YourDiv").innerHTML +http.responsetext
}
}
http.send(params);
}
</script>
</head>
<body>
<form>
<input type="text" id="user" value="user" name="user" />
<input type="password" id="password" value="pass" name="pass" />
<button onclick="submit_ajax(user.name,password.name,user.value,password.value, "submit_file.php");">Submit</button>
</form>
<div id="YourDiv">
<!--Something appears here after callback-->
</div>
This was the first page. Now Use your script in your PHP file(probably, submit_file.php) as you want and then echo the text you want in your div by validation or something.. a sample would be
<?php
$username=$_POST['user'];
$password=$_POST['pass'];
if(validateuser($username,$password)){
if(checkuserpass($username,$password){
echo "You were successfully logged in!";
}
echo "Sorry Username/Password Mismatch";
}
else {
echo "There was an error in your input!Please Correct";
}
?>
Hope you got what you wanted...
The simplest way would be assigning the error message to a variable called (e.g $errorMsg)
the printing it on page using a echo or print function.
<?php
if ($_POST['q']) == NULL ){
$errorMsg =' Please enter your information';
}
?>
Place this code where you want the error to appear
<? print $errorMsg; ?>
I have one field (for zip code), if user enters zip code that matches one in my array and click "go" - they are redirected to the next step, if not - display "out of our service area" message. Form and php script are on the same page. How Do I do redirection inside That's what I have so far.
<form>
<input type="text" id="zipcode" name="zipcode" />
<input type="submit" id="submit" value="GO" />
</form>
<?php
$allowedzips = array("10051", "10061", "10071", "10081");
$input = echo $_POST["zipcode"];
$input = str_split($input);
$message = "Out of our service area";
foreach($input as $zip) {
if (in_array($zip, $allowedzips)) {
$message //redirect goes here
break;
}
}
echo $message;
?>
A PHP redirect is quite easy to do:
header('Location: www.example.com');
exit;
Make sure to exit;, as that will stop the script from executing any further.
I think it would be better to use javascript instead of PHP for how you are looking to do this.
What I would do is add this into the head of your html
<script type="test/javascript">
function checkZipCode(zip) {
var myZipCodes=new Array("10051", "10061", "10071", "10081");
for(i=0;i<myZipCodes.length;i++) {
if (zip = myZipCodes[i]) {
form.submit;
}
else
window.location = "redirectpage";
}
}
</script>
And then on submit call and pass the zip code to checkZipCode.
I would do this in PHP to ensure that you're not tricked on the client side
Use the in_array() function to determine if the element you're looking for is within you list of valid zip codes, and redirect accordingly.