Php 防止脚本在页面刷新时重新执行操作

Php 防止脚本在页面刷新时重新执行操作,php,shopping-cart,Php,Shopping Cart,在过去的一周里,我正在构建自己的php购物车,遇到了一些问题 我设法在购物车中添加了新项目,URL如下所示 http://blah-blah.com/order/index.php?action=add&id=84 问题很简单:如何防止在购物车中再次添加相同的商品 如果有人刷新页面?因为现在每次有人刷新页面时,它都会将特定项目的数量更改为+1 此外,在移动到结帐页面后,如果他们在浏览器中按下后退按钮,数量将再次更改为+1 有什么建议吗?有。设置它们,而不是增加数量 此外,对于此类操作,

在过去的一周里,我正在构建自己的php购物车,遇到了一些问题

我设法在购物车中添加了新项目,URL如下所示

http://blah-blah.com/order/index.php?action=add&id=84
问题很简单:如何防止在购物车中再次添加相同的商品 如果有人刷新页面?因为现在每次有人刷新页面时,它都会将特定项目的数量更改为+1

此外,在移动到结帐页面后,如果他们在浏览器中按下后退按钮,数量将再次更改为+1

有什么建议吗?

有。设置它们,而不是增加数量

此外,对于此类操作,您通常会使用
POST
(而不是
GET
)请求。浏览器知道这一点,狡猾地询问用户是否要重新提交
POST
数据


对于您的用户来说,最干净的方法可能是使用AJAX完成整个工作。如果他们“返回”,他们会毫不费事地返回到他们访问的最后一页。这相当于如何提交堆栈溢出的注释:您不能“返回”到提交步骤并最终编写重复的注释。

正如Tomalak所说,最好使用POST数据进行此类操作。 与POST数据结合使用的另一点是使用重定向头响应用户,即使用户尝试刷新或返回,数据也不会再次被处理

基本示例:

<?php
if( !empty($_POST) ){
  // do stuff with POST datas then
  header("location: mypage.php\n");
  exit;
}
您可以使用

<?php
header("Location: http://www.example.com/"); /* Redirect browser */

我建议采取以下步骤来避免多次提交和后退按钮问题:

  • 如上所述,您应该使用POST方法提交表单,而不是GET
  • 防止来自同一会话的多个表单提交,如下所述:
  • 处理完POST请求后,应重定向到确认URI或更好的URI,如下所示:

    //处理POST请求后重定向
    标题(“位置:“.$”服务器[“请求URI”])
    退出


  • 您好,我没有为您提供编码解决方案,而是为这个问题提供了一个逻辑解决方案试试看它可能对您有帮助,它对我有帮助

    我遇到了同样的问题,我在我的URL(GET变量)中使用了“ShoppingCart?AddToCart=1&…”“,作为了解用户想要向购物车添加产品的一种方式,每次我刷新页面时,都会一次又一次地添加相同的产品

    当我收到AddToCart请求时,我的工作方式是首先执行一个方法,将产品添加到购物车,然后执行另一个方法,该方法将显示购物车的内容(这就是这里的问题)

    我稍微改变了一下逻辑

    现在,每当我收到相同的AddToCart请求时,我都会执行相同的第一个方法将内容添加到购物车中

    但是

    现在,我使用标题(“Location:ShoppingCart?ViewCart=1”),而不是执行第二个方法来显示购物车的内容

    这意味着在执行将内容添加到购物车的第一个方法后,我向我的购物车页面发出查看购物车请求,现在,每次我发出一个AddToCart请求时,它都会将内容正确地添加到购物车中,然后每当我尝试将页面刷新到时,尝试复制AddToCart请求时,我总是以ViewCart请求结束,页面只会显示购物车内容,而不会再添加任何内容将内容放入购物车

    这里的诀窍是,每次我收到ShoppingCart?AddToCart=1&…“时,我都会执行Add函数和header函数,最终在URL中显示“ShoppingCart?ViewCart=1”,而不是原来的ShoppingCart?AddToCart=1&…“

    现在,即使有些人尝试刷新页面或使用浏览器中的“后退”按钮返回页面,他们总是会发出的“ShoppingCart?ViewCart=1”请求,但他们永远不会在URL中看到的“ShoppingCart?AddToCart=1&…”

    就像我说的,我没有一个编码解决方案,而是一个逻辑解决方案


    希望这有帮助

    我知道这个问题已经解决了,但我有一个选择,我为这个问题想出了

    其思想是在前后创建一个$\u POST数据的散列。在本例中,我使用了md5,但您可以使用您想要的任何算法:

    $postHash = md5(serialize($_POST).date("dMY",time()));
    if(!isset($_SESSION['post'])) $_SESSION['post']="Not yet set.";
    
    然后,如果出现以下情况,您只需将通常位于页面顶部的所有处理代码放入:

        if($_SESSION['post']!=$postHash) {
         // Perform actions
        } else {
      echo "Cannot post duplicate data";
    }
    
    然后,在页面底部(或在处理完成且已执行任何数据库调用之后):


    仍然有一些问题,但它似乎工作正常。希望这能有所帮助。

    是的,我想改用POST,但我不确定它是否比GET更好。或者,我仍然可以使用GET选项,仅当购物车中没有新项目时才添加它。现在,用户可以通过自己输入数量并按我添加的更新btn来更改数量。听起来怎么样?它比POST方法好吗?@george:
    POST
    就是为这种事情设计的<代码>获取
    不可用。暗示就在名字里,真的。不,不是。GET's不应该改变任何东西,是可计算和可重复的:@Tomalak:啊,是的,“不,不是”显然是给@george的,不是给你的:)我觉得你的例子有点太简单;)oups忘记了代码格式,所以没有显示。谢谢您的指点。
    $_SESSION['post'] = md5(serialize($_POST).date("dMY",time()));