是否可以通过AJAX调用执行后台PHP服务器任务,该任务不会锁定您的网站

Is it Possible to Perform a background PHP server task from an AJAX call that will not lockup your site?

本文关键字:任务 锁定 网站 是否 调用 AJAX 执行 后台 服务器 PHP 可以通过      更新时间:2023-09-26

我有一个类似的服务器功能

function very_long_task($data) {}

此函数是使用$.ajax()函数客户端调用的。

问题是,当我的服务器端函数very_long_task()被执行时,站点被锁定了。这意味着,如果我试图从不同的选项卡或窗口查看网站的另一个页面,则在very_long_task()功能完成之前,网站将不会加载。

有没有办法绕过服务器端或客户端?

更新日期:2015-11-3

AJAX调用实际上被调用了很多次,因为它循环遍历列表中的所有元素,并对每个元素执行操作。然后对每个元素调用very_long_task()函数。

例如,如果存在20个元素的列表,则very_long_task()函数将被调用20次。这确实有助于该页面的整体响应能力,但对其他页面没有帮助。

更新日期:2015-11-3

此外,这是用WordPress构建的,所以我可以利用它们的一些功能,但我在wp_schedule_single_event方面运气不佳,因为我需要一个返回值。

https://codex.wordpress.org/Function_Reference/wp_schedule_single_event

更新日期:2015-11-3

这是我的的更新视图

function very_long_task($data) {
    session_write_close();
    // Very long task...
    return $data;
}

您需要尽快调用session_write_close()

这是因为当一个页面调用session_start()时,会话文件将被锁定,直到该页面完成执行,或者直到会话关闭。

如果不这样做,任何调用session_start()的页面都将等待解除锁定。

更新

我想我知道发生了什么:

浏览器限制同时连接到服务器的次数,通常在2到10之间。

如果您正在进行20个异步AJAX调用,并且打开开发人员控制台(F12/control-shift-I),您可能会发现并非所有调用都在同时执行。这肯定不会留下额外连接的空间。

注意,session_write_close()仍然是必需的,否则ajax调用将串行执行。

建议

因此,最好只进行一次AJAX调用。如果需要并行性,可以在服务器端派生子进程。

您可能无法使用jQuery,因为您希望从服务器发送数据,并在数据可用时对其进行flush()处理(HTTP流)。

我在WP导入器插件中使用的一个解决方案是根本不使用AJAX,而是执行长期运行的操作,推出HTML和<script>标记来更新UI。

我不完全确定你所说的"锁定"是什么意思,但下面是一些可以尝试的东西:

确保AJAX是异步的

$.ajax({
    url: '/start_very_long_task.php',
    async: true
});

确保您的PHP适应预期的行为

// start_very_long_task.php
function start_very_long_task()
{
    ini_set('ignore_user_abort','on');
    ini_set('max_execution_time', 0)
    session_write_close();
    do_very_long_task();
}
function do_very_long_task()
{
    // Very long task stuff
    // This can recursively call itself without making
    //   making multiple calls to session_write_close(), etc...
}
start_very_long_task();