The first example is using:
HTTP GET request to load the page.
HTTP POST request submit form.
Form's data is stored in session.
HTTP GET request to load the page.
The second example is using goto to "reflow" the buffer, avoiding the additional HTTP request.
HTTP GET request to load the page.
HTTPPOST request submit form.
Buffer is flushed & content is displayed.
Furthermore, the last example doesn't use sessions.
301
<!DOCTYPE html>
<html>
<head>
<!-- ow noez! -->
</head>
<body>
<?php
// A very common scenario in user-flow handling is redirecting user to the page itself after submitting form, e.g.
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['a'])) {
// Suppose there was an error & I've populated the error in $_SESSION.
// Now I would redirect user back to the form. This is because there
// is markup in the upper template hierarchy layer, e.g. "<!-- ow noez! -->"
header('Location: ' . $_SERVER['REQUEST_URI']);
exit;
}
}
?>
<form action="" method="post">
<?php if (isset($time)):?>
<pre>This value is from the past: <?=$time?></pre>
<?php endif;?>
<pre>Next time: <?php $time = time(); echo $time;?></pre>
<input type="submit" name="a" value="back in time!">
</form>
</body>
</html>
goto
<?php
goback:
ob_start();
?>
<!DOCTYPE html>
<html>
<head>
<!-- ow noez! -->
</head>
<body>
<form action="" method="post">
<?php if (isset($time)):?>
<pre>This value is from the past: <?=$time?></pre>
<?php endif;?>
<pre>Next time: <?php $time = time(); echo $time;?></pre>
<input type="submit" name="a" value="back in time!">
</form>
<?php
// A very common scenario in user-flow handling is redirecting user to the page itself after submitting form, e.g.
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['a'])) {
ob_clean();
$_POST = [];
$_SERVER['REQUEST_METHOD'] = 'GET';
goto goback;
}
}
?>
</body>
</html>
Is the goto scenario not superior to 301?
>xkcd
Have you considered using AJAX instead? Then your flow is:
HTTP GET to fetch the webpage
HTTP POST via AJAX to submit the data
Done! Optionally, use JavaScript to update the current view.
Alternatively, you can keep your current code and just move the whole if($_SERVER['REQUEST_METHOD'] === "POST") section to be up where your goto label is. In other words, restructure the program's flow ;)
Related
I have the following problem and feel that the solution is simple but after 8 hours of trying and searching, I am giving up.
I have this simple page:
<?php
// Start the session
$lifetime=600;
session_set_cookie_params($lifetime);
session_start();
?>
<!DOCTYPE html>
<html>
<head>
<title>Change the Yoda!</title>
</head>
<body>
<?php
// Set session variables
$_SESSION["post-data"] = $_POST;
?>
<form action="yoda_is.php" method="POST">
YODA IS: <input type="text" name="name">
<input type="submit">
</form>
</body>
</html>
Upon submit, it sends me to this page:
<?php
// Start the session
session_start();
?>
<!DOCTYPE html>
<html>
<head>
<title>Who is Yoda?</title>
</head>
<body>
<?php
// Echo session variables that were set on previous page
echo "YODA IS " . $_SESSION['post-data'] = $_POST['name'];
?>!
</body>
</html>
The value that you enter in the first page, is successfully being displayed on the second page.
However, once I close the browser window and revisit the second page, the value is no longer there and it returns an error.
My question is simple, what am I doing wrong / do I need to do in order for the value that I entered on the first page, to be there after I revisit the second page?
Thank you so much for your help and suggestions, in advanced.
KR
MD
On your first page remove this:
// Set session variables
$_SESSION["post-data"] = $_POST;
On your second page use this instead:
// If the user filled out the form, set our session variable to the new value
if(isset($_POST['name']))
{
$_SESSION['post-data'] = $_POST['name'];
}
// Echo session variable set above
echo "YODA IS " . $_SESSION['post-data'] . "!";
What I have learnt is: At a time, only HTTP POST or GET method is possible. I have the following piece of code named: index.php
<?php
if($_SERVER['REQUEST_METHOD'] == "POST") {
echo "Request Method is: ". $_SERVER['REQUEST_METHOD'] .'<br>';
echo "Get variable is: " . $_GET['getname'] . '<br>';
echo "Post variable is: " . $_POST['posttitle'];
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Testing Get or Post</title>
</head>
<body>
<form action="" method="POST">
<input type="text" name="posttitle" value="somepost"/>
<button type="submit">Submit</button>
</form>
</body>
</html>
I navigate the form via : http://localhost/testing/index.php?getname=someget. I submit the form, and the form data is sent via HTTP POST method.
Now my question is:
In this scenario, the HTTP method is POST, and the GET variable $_GET['getname'] should have been unavailable. But, both POST and GET variables are available and printed.
This is just down to PHP having poor names for $_GET and $_POST.
$_GET will contain data from the query string of the requested URL. This is completely independent of the request method used.
PHP probably picked the name because an HTML form with method="GET" will put the data in the query string, but that isn't the only way a query string can be created.
I'm working on a database-driven quiz that lets users select a series of answers, then submit the results via a form. It was working great, when it suddenly blew up, and I haven't been able to find the problem.
So before I get into the more complex stuff, I'd like to go back to square one and just make something simple work - like passing a hidden value to another page that echoes that value.
Here's the code for my first page # mysite/form.php:
<html>
<head>
</head>
<body>
<!-- g1/form.php -->
<div id="quiz" rel="key">
<form action="form2.php" method="post" id="quiz">
<input type="hidden" name="PreviousURL" id="url" />
<input type="submit" value="Submit Quiz" />
</form>
</div><!-- quiz-container -->
</body>
</html>
And here's the code for the second page:
<html>
<head>
</head>
<body>
<?php ini_set('display_errors', 1);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
echo $_POST['PreviousURL'];
}
echo 'XXX';
?>
</body>
</html>
I also tried moving the closing bracket, like this:
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
}
echo $_POST['PreviousURL'];
echo 'XXX';
In both cases, when I click the submit button and am forwarded to form2.php, I see "XXX," but there's no value for $_POST['PreviousURL'].
I must have accidentally deleted or modified something, because it seems so simple, and it worked fine before. Can anyone tell me what the problem is?
there isn't a value for the hidden input.
In your form script you have missed out the value="" from the hidden input. This is the reason why nothing is displaying on the second page.
So I am pretty new to PHP, I have done and learnt lots of console based experience so I'm not a full beginner to programming. But I decided to learn how to database because its always fascinated me, and I've learnt the basic HTML and CSS and JS, and now basic PHP and SQL, but putting into action is getting weird on me.
I've figured out how to manipulate and make databases through PHP code and stuff like that, but they were all simple things and in one file, I am going for a bigger project and I need to put all the PHP's in separate files, this is the problem.
say my 'index.php' file is so:
<!DOCTYPE html>
<html>
<head>
<?php include 'other.php' ?> //Problem 1
</head>
<body>
<FORM method="POST" action="other.php">
<INPUT type="text" name="textTest" value="<?php print $input; ?>">
<INPUT type="submit" name="subTest" value="TEST" >
</FORM>
</body>
</html>
and my 'other.php' is :
<?php
$input = "";
if (isset ($_POST['subTest']))
{
$input = $_POST['textTest'];
//header("Location : index.php");
}
header("Location: index.php"); //Problem 2
?>
so my problems:
Problem 1, if I don't include the 'other.php' file, there is an error when I try print the: value = "print $input"
Problem 2, if I don't redirect with 'header', it obviously doesn't redirect and go back to the 'index.php' which I want to happen. BUT with it there, it causes a TOO_MANY_REDIRECT error. I found this is a problem caused by the include which can't be removed for Problem 1 reasons.
Problem 3, I found out I could move the 'header' function to where it is commented out, but then the value="..." doesn't stay on submit.
Problem 4, if I completely get rid of the 'header' redirect, and change the form's action to 'index.php', then I get the 'Confirm Form Resubmission' thing I want to avoid.
So I hope that is a mouthful someone understands and can help with, and thankyou in advanced.
include does what it sounds like, it includes the file into the parent, essentially the same as copy and pasting the content into it.
So to fix your problem, 1st change the forms action to index.php (so it posts to its self), and remove the redirect all together:
<?php include 'other.php' ?>
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<FORM method="POST" action="index.php">
<INPUT type="text" name="textTest" value="<?php print $input; ?>">
<INPUT type="submit" name="subTest" value="TEST" >
</FORM>
</body>
</html>
other.php:
<?php
$input = "";
if (isset ($_POST['subTest'])){
$input = $_POST['textTest'];
}
Note that i also moved the include to the 1st line in index.php, before any html output.
This is not strictly required in this instance, but is a good practice, as you are unable to set headers (eg for a redirect) after the response body is sent to the output stream
EDIT
If you want to avoid form resubmits on refresh, then you are correct that you would need to submit to a seperate endpoint and redirect.
To do that you would need to pass the posted data back to the index file, as the redirect is a new (GET) request, so the post data is lost.
The two main ways to do that would be with SESSION or URL parameters.
I'll show how to do it with parameters:
Dont include the destination file:
<?php
//get value from url parameter, or set to empty string if parameter not present
$input = isset($_GET['input'])? $_GET['input'] : '';
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<FORM method="POST" action="other.php">
<INPUT type="text" name="textTest" value="<?php print $input; ?>">
<INPUT type="submit" name="subTest" value="TEST" >
</FORM>
</body>
</html>
Then append the required data to the redirect url as parameters
other.php:
<?php
$input = "";
if (isset ($_POST['subTest'])){
$input = $_POST['textTest'];
header("Location: index.php?" . http_build_query(['input'=>$input]));
die(); //always stop execution after redirect
}
//if post data not sent, something went wrong, so set $input parameter to error message
header("Location: index.php?" . http_build_query(['input'=>'No Data posted']));
die(); //always stop execution after redirect
In other.php at the last line try require-ing the index.php instead of redirrecting.
Also remove the inclusion of other.php in index.php .
$input = "";
if (isset ($_POST['subTest']))
{
$input = $_POST['textTest'];
}
require_once 'index.php';
?>
Suppose, I have two pages: page01.php and page02.php (their code is presented below).
If I leave action attribute in the form on page01.php empty (i.e. action=""), then access page01.php, fill in the form, press submit, then access page02.php - it all works fine (i.e. $_SESSION variable stores the data submitted on page01.php and can be accessed and viewed on page02.php as expected).
However, when I try to make the form send the user to page02.php (by changing the action atrribute to action="page02.php") it looks like the $_SESSION global variable doesn't store data from page01.php.
My question is: does this happen because the user is redirected to page02.php immediately upon submission of form and the code between php tags on page01.php does not get executed?
I'm aware I can use $_GET or $_POST on page02.php to achieve the desired behavior, but I'm just trying to understand the way action attribute and $_SESSION interact. Thank you.
Page01.php:
<html>
<head>
<title>Page 01</title>
</head>
<body>
<h1>Please fill this form</h1>
<form action="" method="post">
Name: <input name="username">
<input type="submit" value="send">
</form>
<?php
session_start();
if(isset($_POST['username'])) {
$_SESSION['username']=$_POST['username'];
}
?>
</body>
Page02.php:
<html>
<head>
<title>Page 02</title>
</head>
<body>
<h1>Another temporary page is working</h1>
<?php
session_start();
$expectedName = "Bob";
if($_SESSION['username'] == $expectedName) {
echo "Welcome, Bob!";
}
else {
echo "Access denied. You are ". $_SESSION['username'] . ", not Bob.";
}
?>
</body>
action attribute is attribute you specify where the script that will need to be run after submitting.
so if you want user to be redirected after form has been submitted, you use header() function.