【问题标题】:How can I set a max on the number of users visiting a page [closed]如何设置访问页面的用户数量上限[关闭]
【发布时间】:2019-03-17 12:57:45
【问题描述】:

我目前正在开发一个带有编辑按钮的应用程序:

我的编辑按钮:

<th title="Edit task" class="edit" style="float: right; $color;">
    <?php
    echo "<a href=edit.php?id=" . $row["id"] . ">
              <i class=material-icons>edit</i>
          </a>";
    ?>      
</th>

我的目标是一次只有一个人可以编辑一篇文章。这甚至可能吗?如果是我该怎么办?

【问题讨论】:

  • 如果你有登录用户,你可以通过很多努力实现非常接近的目标......但我会说一般来说它非常复杂/不可能做到 100%......你需要js 回调以指示何时有人仍在与登录用户一起查看
  • 你使用什么数据库?
  • @MaximFedorov phpmyadmin
  • phpmyadmin 是 mysqli 数据库的用户界面 ;-)
  • 对不起@Lithilion...我还是个学生:)

标签: php html max


【解决方案1】:

如果您只想禁用按钮以避免并发编辑,那么这是一个糟糕的主意,因为用户总是可以通过直接链接打开编辑页面。其实你需要实现并发控制。

您可以将记录锁定到并发控制。

例如,您可以使用以下简单的算法来实现并发控制:

  1. 您将包含锁定结束时间的参数添加到文章
  2. 在编辑页面上:如果锁定时间大于当前时间,则将此时间与当前时间进行比较,然后通知用户不可能修改文章,否则向用户显示编辑页面
  3. 在编辑页面上:如果您向用户显示文章的编辑页面,那么您会增加锁定参数的结束时间,例如以 5 分钟为增量
  4. 如果用户完成记录修改并保存,则应重置锁定结束日期

但是,您可以实现乐观锁定,而不是这种算法。

乐观锁定提供用户同时打开一个编辑页面,但它禁止以并行方式保存记录。这是避免并行修改记录的麻烦的更好方法

乐观锁定包括接受或拒绝记录的更改以取决于记录版本。

它的工作原理如下:每篇文章都有一个“版本”参数,其中包含记录修改的数量。一个用户打开版本等于 1 的文章的编辑页面,而另一个用户同时打开它。他们都保存了同一篇文章。首先,您收到一个记录修改请求并将存储记录的版本与更新记录的版本进行比较,如果它们彼此相等,那么您应该接受更改并将更新的记录保存在存储中并以增量增加“版本”参数1 否则,您应该拒绝更改。作为该算法的结果,存储记录的版本将等于 2。接下来,您获得第二个请求并再次比较版本,但由于存储记录的版本等于 2,而来自第二个请求的更新记录的版本等于 1更改被拒绝。当然,您必须通知用户其更改被拒绝,并让用户能够更新新的记录变体

【讨论】:

    【解决方案2】:

    这是我在我的应用程序中所做的:

    当用户按下编辑按钮时,将时间戳记录在数据库中并将用户重定向到编辑页面。在编辑页面中设置一个计时器并将其显示给可以编辑记录的用户,直到计时器用完。

    例如,根据您的记录,您可以考虑让用户在 2 分钟内编辑一条记录。时间将从 01':59'' 开始,一直到 00':00''。

    对于其他用户,当点击编辑按钮时,您应该检查是否有其他用户正在编辑该记录,您可以通过从登录数据库和现在计算时间来做到这一点。

    如果用户在2分钟内编辑记录并保存,你可以删除编辑日志让其他用户编辑。

    【讨论】:

      【解决方案3】:

      在我看来这不是完全可能的。

      但尝试使用以下方式。

      您可以在数据库中添加两列“打开”和“时间”

      如果有人正在编辑它,请将“打开”设置为“真”或“假”。还要为“时间”列设置时间戳。编辑时每隔几秒更换一次时间戳。

      如果其他人打开它,请检查“打开”列,如果它是“真”,则计算从“时间”列传递的时间。如果超过一定时间(例如 2 或 3 分钟),则假设其他用户不再进行编辑并允许该用户进行编辑。

      为了清楚起见,

      您需要添加一个 ajax 调用,它会在每分钟/秒后更新您的时间戳。 如果您在编辑页面中。 因此,如果有人关闭浏览器,则时间戳将不会更新,并且在下一个用户尝试编辑之后,如果时间戳较旧然后 2/3 分钟,则允许编辑该用户。因为我们假设用户关闭了选项卡或浏览器,所以标志没有更新,但时间戳较旧。

      这不是完美的解决方案,但您可以尝试一下。

      【讨论】:

        【解决方案4】:

        有简单的方法,也有困难的方法。

        简单方法:使用时间戳检查保存的并发性。

        您可以简单地将时间戳(通常命名为 update_at)与您的数据一起添加到您的数据库中。

        您将时间戳放在页面中(或者更安全的 $_SESSION 变量),以便在发布更改时也发布时间戳。在服务器端,您验证数据库中的时间戳是否与您发布的时间戳相同,如果不是,则返回一条消息,说明该帖子已被编辑。

        如果您关心用户输入的内容(并且大多数情况下您应该关心),您始终可以并排显示两个编辑并允许他选择/编辑其中一个。

        艰难的方式:在数据库中存储锁定时间戳

        您可以使用与简单方法相同的方式为您的数据添加时间戳(但这次我们将其称为 last_edit_time)。

        当用户进入编辑页面时,您可以这样做:

        • 您检查 last_edit_time 是否距离当前时间 30 秒
          • 如果不到 30 秒,您会返回一条消息,说明正在编辑数据
          • 如果超过 30 秒,请将 last_edit_time 的值设置为当前时间并显示您的编辑页面
        • 一旦用户进入编辑页面,您将启动 15 秒的 javascript 间隔
          • 每隔 15 秒,您会向服务器发送一个异步请求 (Ajax),告知服务器将 last_edit_time 更新为当前时间。我们每 15 秒发送一次,这样如果异步调用需要很长时间,则在第 30 秒开始编辑的用户不会加载页面。

        这样做可以确保只有一个用户可以同时访问该页面。如果您想让它更加安全,您可以在您的 last_edit_time 旁边添加用户 ID,以便在保存时验证它是否是同一用户。

        您甚至可以在用户完成编辑后将 last_edit_time 设置为 null。这将尽快为所有人解锁数据。

        当然,在某些极端情况下,两个用户会在同一秒内打开页面。要解决此问题,您始终可以提高时间戳的精度(毫秒而不是秒)。

        【讨论】:

          【解决方案5】:

          您可以很容易地做到这一点,请按照以下步骤操作。

          1) 创建一个表名作为你列的editLog id,member_id/user_id,is_editable(默认1)

          2) 现在初始阶段表是空的,当用户单击编辑时,第一个用户来编辑触发 AJAX,同时从数据库中检查表中是否没有任何数据,然后允许他进行更改(和当您保存或更新表中的数据时,请检查成员 ID 以确保成员相同),如果数据退出,则给他警告错误..

          如果您仍然有混淆评论,请按照这些步骤操作。

          【讨论】:

            【解决方案6】:

            您从中获取 $row["id"] 的表中再添加一列,并将该列命名为 ipAddress,默认值为 null。

            现在,当用户转到“/edit.php?id=$id”时,用用户 ip 更新表的 ipAddress 列。可以通过JS或者Server变量轻松获取用户ip地址。

            在edit.php之后,您可以轻松检查当前ip是否等于ipAddress,例如:

                if($_SERVER['REMOTE_ADDR'] == $ipAddress){
                  // Allow edit
                }
                else {
                  // Donot allow edit
                }
            

            编辑完成或关闭浏览器后,您可以将 ipAddress 设置为 null。

            【讨论】:

              【解决方案7】:

              我做了一些研究,发现这真的很难完成......你可以做的是检查文章是否有最近的更新(与 SO 上的待编辑相同)

              【讨论】:

              • 简单问题。你为什么要这么做?
              • @ZainFarooq 防止文章同时被编辑
              • 您对数据库有任何时间担忧或漏洞吗?
              • 意味着多个用户同时使数据库易受攻击
              • @ZainFarooq 只是任务完成时的日期戳
              【解决方案8】:

              根据我的理解,你的问题的解决方法很简单。

              • 首先,制作一个或多个表,您将在其中记录用户以自己的方式进行的更新查询
              • 制作一个脚本,该脚本将执行您在第一步中创建的表的最旧查询,然后在成功运行更新后删除该查询
              • 学习Cron Jobs
              • 在一定的时间间隔内为该脚本创建一个cron job

              享受你的生活:)

              【讨论】:

              • 我不想学cron :(。有没有脚本或者php的解决方案?
              • 可以通过php来完成。不用担心
              • 是否还有 localhost 解决方案而不是 linux 服务器解决方案
              • 使用该解决方案我只能每 5 分钟刷新一次页面我希望每 1 分钟刷新一次
              猜你喜欢
              • 2015-07-01
              • 1970-01-01
              • 1970-01-01
              • 2021-09-26
              • 1970-01-01
              • 1970-01-01
              • 2020-08-03
              • 1970-01-01
              • 2014-10-24
              相关资源
              最近更新 更多