PHP:为什么我的防洪脚本滞后?

时间:2016-03-01 06:05:40

标签: php

感谢您的阅读。

我有一个输入字段,它将XMLHttpRequest中的内容发送到php脚本。该脚本使用字段中的POST数据查询数据库并返回结果。

因为使用onkeyup调用XMLHttpRequest,所以输入一个冗长的值会在短时间内发送多个调用。为了解决这个问题,我编写了一些代码,用于创建时间戳,将其加载到会话中,休眠,然后重新检查时间戳。如果时间戳增加,则意味着后续调用并且脚本应该中止。否则脚本将执行。这是代码。

$micro = microtime(true);
$_SESSION['micro'] = $micro;
usleep(500000); // half a second
if ($micro < floatval($_SESSION['micro']))
{
    // later call has been made, abort
    echo 'abort';
    exit;
}
else
{
    // okay to execute
}

代码似乎首先按预期工作。如果我在输入字段中添加或删除一个或两个字符,结果会很快显示。

但是,如果我尽可能快地输入一个好的12个字符,那么会有很长的延迟,有时会延迟2到3秒。

我正在使用localhost,因此没有连接问题。查询也很小,抓取一个包含特定行中单个单词的列。

我还将XMLHttpRequest设置为异步,因此也应该没问题。

xmlhttp.open("POST","/test/",true);

如果我删除防洪代码,输入该字段会立即返回结果 - 无论我输入多少和多快。

这几乎就像usleep()不断堆叠自己或其他东西。

我自己想出了这个代码,我能做到最好。不知道为什么它的表现不如预期。

非常感谢帮助,谢谢!

2 个答案:

答案 0 :(得分:3)

当您使用session_start()打开会话时,PHP会锁定会话文件,以便在另一个请求打开时对相同会话的任何后续请求将被阻止,直到会话关闭(您完全正确使用&# 34;堆积&#34;你怀疑发生了这种情况。)

您可以致电session_write_close()关闭会话并解除锁定,但在这种情况下这可能不会有所帮助。

每次按下按键时发生的事情,发出请求并在前一个请求完成时备份每个请求,一旦会话被释放,其他一个请求将打开会话并休眠,并且这种情况一直持续到他们都完成了。

相反,我在Javascript中创建一个全局变量,指示请求是否正在进行中。如果是,则不要发送另一个请求。

这样的事情:

<script>
var requesting = false;

$('#input').on('keyup', function() {
    if (requesting) return ;

    requesting = true;
    $.ajax({
        url: "/url"  
    }).done(function() {
        requesting = false;
    });
}
</script>

答案 1 :(得分:0)

drew010的答案完美地解释了我的问题(谢谢!)。但是他们的代码示例,从我收集到的解释方式(我没有尝试过),与我需要的相反。如果用户键入“hello”,h将被发送,但ello可能不会,除非结果使其及时返回。 (对不起,如果这是一个错误的假设)

这是我自己提出的解决方案。

<input type="text" onkeyup="textget(this.value)" />

<script>
var patience;
function ajax(query)
{
    // XMLHttpRequest etc
}

function textget(input)
{
    clearTimeout(patience);
    patience = setTimeout(function(){ajax(input)},500);
}
</script>

当在输入字段中按下某个键时,它会将其当前值传递给textget函数。

textget函数清除现有的计时器(如果有)并启动一个新计时器。

当计时器完成倒计时时,它会将值进一步传递给ajax函数以执行XMLHttpRequest。

因为每次调用textget函数时都会重置计时器,如果在计时器结束前(0.5秒)进行了新的调用,则前一个调用将丢失并被新的调用替换。

希望这有助于某人。