【问题标题】:How can I stop PHP sleep() affecting my whole PHP code?如何阻止 PHP sleep() 影响我的整个 PHP 代码?
【发布时间】:2010-12-09 16:46:49
【问题描述】:

所以,在我的街机 howlingdoggames.com 上。我有一个积分系统,每次你访问一个有游戏的页面时都会给你一个积分。为了减少滥用,我想做一些延迟,所以它只在 45 秒后授予。这是我尝试过的:

if ($_SESSION['lastgame'] != $gameid) {
    sleep(45);
    $points = $points + $game_points;
    $_SESSION['lastgame'] = $gameid;
}

但这似乎只是让我的整个网站停止了 45 秒,因为它在 index.php 中,以及我网站的许多其他代码。

反正我可以隔离那段代码,所以它只做声明

$points = $points + $game_points;

等待 45 秒?

【问题讨论】:

    标签: php sleep delay


    【解决方案1】:

    PHP 中(大部分)没有多线程。您可以通过 Unix 系统上的分叉进程来做到这一点,但这无关紧要,因为多线程并不是您真正想要的。你只需要这样的简单逻辑:

    $now = time();
    session_start();
    $last = $_SESSION['lastvisit'];
    if (!isset($last) || $now - $last > 45) {
        $points = $_SESSION['points'] ?? 0;
        $_SESSION['points'] = $points + 10;
        $_SESSION['lastvisit'] = $now;
    }
    

    基本上只在你上次给分的时间增量大于 45 秒时才给分。

    【讨论】:

    • 对此的奇怪随机投反对票。只是好奇是有原因还是失败的战术性投票失败?
    • 不是我,但代码示例并没有真正回答这个问题,因为这只会在您访问新游戏后才会发生 + 您在 $_SESSION['last'] 中有错字。
    【解决方案2】:

    这是会话阻止您的脚本。不是“PHP 中没有多线程”。 sleep() 之前的 session_write_close() 将解决阻塞整个脚本的问题。但可能不适合您的问题。

    所以你必须使用 js 和 AJAX 的 settimeout 来保存奖金。

    来自 php.net 中 sleep() 的评论: http://www.php.net/manual/en/function.sleep.php#96592

    请注意, sleep() 会延迟当前会话的执行,而不仅仅是脚本。考虑以下示例,其中两台计算机从浏览器调用相同的脚本,除了睡眠之外什么都不做。

    【讨论】:

    • 有谁知道该评论所说的是否属实?它的投票率很低
    【解决方案3】:

    您不能,但您可以将此代码设为 javascript 代码,并使用 AJAX 节省奖金。

    【讨论】:

    • 怎么样?无论如何,您都要在服务器中验证 AJAX 调用。
    【解决方案4】:

    PHP 中没有多线程,所以sleep() 总是会阻塞你的整个脚本。

    你应该解决的方法是记录最后一场比赛的时间,如果超过45秒才奖励积分。

    <?php
    session_start();
    if (!isset($_SESSION['last_game_time'])
        || (time() - $_SESSION['last_game_time']) > 45) {
    
        // code to award points here
    
        $_SESSION['last_game_time'] = time();
    }
    

    请记住,如果用户禁用 cookie,他们仍然可能滥用此功能(因此他们将没有会话数据)。因此,如果这真的让您担心,请在允许他们使用该功能之前检查他们是否启用了 cookie(可能有几个问题涵盖了这一点)。

    【讨论】:

      【解决方案5】:

      不要阻塞脚本,而是保存会话中的当前时间,不要添加点并让页面呈现。然后在以后的页面查看中,如果您发现会话中保存的时间超过 45 秒,请添加点,将它们存储在您需要的任何位置,然后清除时间。

      【讨论】:

        【解决方案6】:

        不,不是直接的。您需要采用不同的方法,例如记住上次访问的时间戳,并且仅在此后经过足够长的时间后才添加积分。

        【讨论】:

          猜你喜欢
          • 2018-11-10
          • 2013-02-17
          • 1970-01-01
          • 2017-10-17
          • 1970-01-01
          • 2013-01-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多