Simple PHP Post-redirect-get Code Example

Simple PHP Post-Redirect-Get code example

Simplest scenario:

if ($_POST) {
// Execute code (such as database updates) here.

// Redirect to this page.
header( "Location: {$_SERVER['REQUEST_URI']}", true, 303 );
exit();
}

Use REQUEST_URI. Do not use PHP_SELF as in most CMS systems and frameworks PHP_SELF would refer to /index.php.

I am confused about PHP Post/Redirect/Get

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.

Understanding the post/redirect/get pattern

As you may know from your research, POST-redirect-GET looks like this:

  • The client gets a page with a form.
  • The form POSTs to the server.
  • The server performs the action, and then redirects to another page.
  • The client follows the redirect.

For example, say we have this structure of the website:

  • /posts (shows a list of posts and a link to "add post")

    • /<id> (view a particular post)
    • /create (if requested with the GET method, returns a form posting to itself; if it's a POST request, creates the post and redirects to the /<id> endpoint)

/posts itself isn't really relevant to this particular pattern, so I'll leave it out.

/posts/<id> might be implemented like this:

  • Find the post with that ID in the database.
  • Render a template with the content of that post.

/posts/create might be implemented like this:

  • If the request is a GET request:

    • Show an empty form with the target set to itself and the method set to POST.
  • If the request is a POST request:

    • Validate the fields.
    • If there are invalid fields, show the form again with errors indicated.
    • Otherwise, if all fields are valid:

      • Add the post to the database.
      • Redirect to /posts/<id> (where <id> is returned from the call to the database)

PHP Redirect with POST data

Generate a form on Page B with all the required data and action set to Page C and submit it with JavaScript on page load. Your data will be sent to Page C without much hassle to the user.

This is the only way to do it. A redirect is a 303 HTTP header that you can read up on http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html, but I'll quote some of it:

The response to the request can be
found under a different URI and SHOULD
be retrieved using a GET method on
that resource. This method exists
primarily to allow the output of a
POST-activated script to redirect the
user agent to a selected resource. The
new URI is not a substitute reference
for the originally requested resource.
The 303 response MUST NOT be cached,
but the response to the second
(redirected) request might be
cacheable.

The only way to achieve what you're doing is with a intermediate page that sends the user to Page C. Here's a small/simple snippet on how you can achieve that:

<form id="myForm" action="Page_C.php" method="post">
<?php
foreach ($_POST as $a => $b) {
echo '<input type="hidden" name="'.htmlentities($a).'" value="'.htmlentities($b).'">';
}
?>
</form>
<script type="text/javascript">
document.getElementById('myForm').submit();
</script>

You should also have a simple "confirm" form inside a noscript tag to make sure users without Javascript will be able to use your service.

PHP - Redirect and send data via POST

You can't do this using PHP.

As others have said, you could use cURL - but then the PHP code becomes the client rather than the browser.

If you must use POST, then the only way to do it would be to generate the populated form using PHP and use the window.onload hook to call javascript to submit the form.

How to keep POST method's input values with post/redirect/get?

You need to transport those values via GET.

There are two options to do that:

  1. sessions
  2. URL query parameters

If you simply save the data in the session, you can read it from there and re-populate the form. If you put it into the URL, you can read it from there; but obviously the URL will contain a lot of data then.

Reading it from a session the data will not be unique to the specific page/redirect, but anyway you open that page again within the same session will show the same data. Passing the data via the URL will make it unique to the specific request.

As a middle ground, you can save the data in the session tied to a specific random id, redirect with this id in the URL (e.g. example.com/foo.php?i=12345), the re-populate the data from the session with the specific id.

POST REDIRECT GET in form that submits to itself duplicate entries in database

Below is sample code if you want try.

<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
Name: <input type="text" name="name">
Email: <input type="text" name="email">
Password: <input type="password" name="password">
<input type="submit" value="submit" name="send">
</form>

PHP Code and common.php is database connection file

<?php
require_once "common.php";

if(isset($_REQUEST['send']))
{
$name = $_POST['name'];
$email = $_POST['email'];
$password = $_POST['password'];

$check = "SELECT * FROM user WHERE name = '".$name."' AND email = '".$email."' AND password = '".$password."'";
$check_result = mysql_query($check) or die(mysql_error());

if(mysql_num_rows($check_result) > 0)
{
header('Location : post.php');
}
else
{
$sql = "INSERT INTO user (name,email,password) VALUES ('$name','$email','$password')";
$result = mysql_query($sql) or die(mysql_error());
}
}
?>

post/redirect/get

The request alone isn't a problem, especially that the alternative gives a pretty bad user experience.

However, when using a site with load balancing and/or database replication, you need to take care to ensure that the GET after POST will see the data that has been posted.

When using load balancing and caching, this is sometimes solved with "sticky sessions" that direct the same user to the same machine, so data stored in a write-through cache on that machine will be current.

When using database replication, GET requests after POST may need to read directly from the "primary" database, instead of a local "secondary" as usual.



Related Topics



Leave a reply



Submit