PHP应用程序保证不重新发布

时间:2010-01-10 19:25:15

标签: php url-routing session-variables

我可能不知道要搜索什么来得到这个答案,所以如果已经处理过,请指出正确的帖子。

现在,我有一个小的自定义CMS,我想确保用户不通过刷新页面重新提交他们的$ _POST数据。所以我做了类似的事情:

<?
  //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;

  }
?>

当脚本重新加载时,我使用会话变量并废弃会话。

我想知道是否有人有更好的方法来解决这个问题。这很麻烦,但我一直在寻找更高的效率。

感谢。

编辑:顺便说一下,当你发布一个我正在做的事情似乎不清楚的时候,stackoverflow.com就会以某种方式做到这一点,但是当他们在这里时,他们也会做一个永久链接。 / p>

4 个答案:

答案 0 :(得分:1)

您实际上实现了所谓的Post-Redirect-Get pattern,这绝对是一种正确的方法。我自己这样做。我经常使用它,我通常在我的基本控制器类中实现一些辅助函数来帮助我使用它:

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;
}

我通常将它与REST样式的URL一起使用,因此POST请求将执行它必须做的任何事情,使用prgRedirect()将一些数据保存到会话,然后将其重定向回相同资源的GET URL /页。 GET方法的处理程序将在执行的顶部调用getPrgData(),并查看会话数据中是否有任何内容。

答案 1 :(得分:0)

如果重要的是用户不插入相同的数据我确定你的数据库中必须有一些独特的列(比如标题可能?)。所以只需检查这个标题是否已经存在。你不需要以任何方式使用任何会议

答案 2 :(得分:0)

怎么样:
1.生成随机字符串(uniqid或md5)
2.将其存储在会话中并以形式输入隐藏的输入 3.检查表单值和会话值 - 如果匹配 - 处理表单。清除会话值。

答案 3 :(得分:0)

这里实际上有两个问题:

  • 当数据已经保存并且您位于保存数据的页面中时,用户点击浏览器中的刷新按钮
  • 用户点击浏览器中的“后退”按钮,再次点击“提交”按钮。

在第一种情况下,最好的方案是遵循GET-after-POST模式,您可以使用header("location:somewhere_else.php")调用来重定向用户。这样您就不必担心连续两次被调用,因为您发布数据的页面不在浏览器的历史列表中(因为服务器已返回302标题)。

第二种情况会受到更多伤害,因为GET-after-POST无效。如果用户提交表单两次,您可以将数据保存两次。在这种情况下,可能有几种解决方案:

  • 在您发送给客户端的每种表单中放置一个“表单标识符”(随机字符串)。当客户端提交表单时,请检查会话数据中是否已有此类标识符。如果您没有,请保存表单数据并将用户会话中的标识符记为“已使用”。如果您在会话数据中找到标识符,请不要保存任何内容 - 它是重复的。
  • 检查数据库中是否提供了完全相同的值。如果匹配,请不要保存副本。但是,用户可能已点击“返回”按钮,更改了某些数据,然后重新提交表单。