代码之家  ›  专栏  ›  技术社区  ›  jay

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

  •  1
  • jay  · 技术社区  · 15 年前

    我可能不知道要搜索什么才能得到这个答案,所以如果这个问题已经解决了,请给我指出正确的帖子。

    现在,我有了一些定制的CMS,我想确保用户不会通过刷新页面来重新提交他们的$_日志数据。所以我做了这样的事情:

    <?
      //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在你发布一个问题的时候会做些什么,如果我在做什么看起来不清楚,但是他们在做的时候也会做一个永久链接。

    4 回复  |  直到 15 年前
        1
  •  1
  •   zombat    15 年前

    实际上,您已经实现了所谓的 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() ,然后重定向回相同资源/页面的获取URL。get方法的处理程序将调用 getPrgData() 在执行的顶部,查看会话数据中是否有任何内容。

        2
  •  0
  •   antpaw    15 年前

    如果用户不插入相同的数据很重要,我确信数据库中一定有一些独特的列(比如标题?)。所以只要检查这个标题是否已经存在。你不需要那样使用任何会话

        3
  •  0
  •   a.yastreb    15 年前

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

        4
  •  0
  •   naivists    15 年前

    这里实际上有两个问题:

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

    在第一个方案中,最好的方案是遵循使用 header("location:somewhere_else.php") 调用以重定向用户。这样就不必担心连续两次被调用,因为发布数据的页面不在浏览器的历史记录列表中(因为服务器返回了302个头)。

    第二种情况会更伤人,因为“后发”没有帮助。如果用户提交表单两次,则可以保存数据两次。在这种情况下,可能有几种解决方案:

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