开发者

PHP Application guarantee no re-post

I might not have known what to search for to get this answer so please point me to the correct post if this has been dealt with already.

Now then, I have a little custom CMS and I want to ensure users don't re-submit their $_POST data by refreshing the page. So I've done something like this:

<?
  //Start a session to hold variables I want after my redirect
  session_start();
  if($_POST){ 

    //Do some php stuff and if I'm happy with the results...
    $_SESSION['some_vars'] = $whatever;

    //Bring me back here but without the $_POST data
    header('Location: '.THIS_PAGE);
    exit;

  }
?>

When the script reloads I use my session variables and trash the session.

I'm wondering if anybody has a better way to handle this. It's fairly non cumbersome but I'm always looking for more efficiency.

开发者_开发知识库

Thanks.

EDIT: By the way, stackoverflow.com does this somehow when you post a question if what I'm doing seems unclear, but they also make a permalink while they're at it.


You have actually implemented what is called the Post-Redirect-Get pattern, and it is absolutely a correct way to do this. I do this myself. I use it so often, I usually implement some minor helper functions into my base controller classes to help me use it:

public function prgRedirect($url = null, $sessionData = null)
{
    if ($sessionData !== null) {
        if (! isset($_SESSION)) session_start();
        $_SESSION['_PRG'] = $sessionData;
    }
    if ($url === null) $url = $_SERVER['HTTP_REFERER'];
    header("Location: ".$url);
}

public function getPrgData()
{
    if (! isset($_SESSION)) session_start();
    if (isset($_SESSION['_PRG'])) {
        $data = $_SESSION['_PRG'];
        unset($_SESSION['_PRG']);
    }
    else {
        $data = null;
    }
    return $data;
}

I usually use it with REST-style URLs, so a POST request will do whatever it has to do, save some data to session using prgRedirect(), which then redirects back to the GET url for the same resource/page. The handler for the GET method will call getPrgData() at the top of the execution and see if there's anything in the session data.


if its important that user dont insert the same data I'm sure there must be some unique column in your database (like headline maybe?). so just check if this headline already exists. you wont need to use any sessions that way


What about:
1. Generate random string (uniqid or md5)
2. Store it in session and put in into hidden input at the form
3. Check form value and session value - if it matches - process the form. Clear the session value.


There are actually two problems here:

  • users hitting the refresh button in their browser when the data is already saved and you are in a page which saves the data
  • user hits the "back" button in the browser and clicks "submit" button once again.

In the first scenario, the best scheme is to follow the GET-after-POST pattern where you use the header("location:somewhere_else.php") call to redirect the user. This way you do not have to worry about being called two times consecutively, since the page where you posted the data, is not in the browser's history list (because the server had returned 302 header).

The second scenario hurts a bit more, because the GET-after-POST does not help. If the user submits the form twice, the you may save the data twice. In this case, there may be several solutions:

  • put a "form identifier" (a random string) in every form you send to the client. When client submits the form, check if you already have such identifier in session data. If you don't have it, save form data and remember the identifier in user's session as "already used". If you find the identifier in session data, don't save anything - it's a duplicate.
  • check the database for exactly the same values that are submitted. If they match, do not save a duplicate. However, the user may have clicked "back" button, changed some piece of data and then re-submitted the form.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜