Php 关闭连接后继续处理
在PHP中是否有一种方法可以关闭连接(本质上是告诉浏览器没有更多的数据)但继续处理。我考虑的具体情况是,我希望提供缓存数据,然后如果缓存已过期,我仍会提供缓存数据以获得快速响应,关闭连接,但继续处理以重新生成和缓存新数据。本质上,唯一的目的是让网站看起来更具响应性,因为当用户等待内容重新生成时,不会出现偶尔的延迟 更新: 加上有最接近的答案,我一直在寻找。为了向一些人澄清,我正在寻找能够实现以下步骤的东西:Php 关闭连接后继续处理,php,Php,在PHP中是否有一种方法可以关闭连接(本质上是告诉浏览器没有更多的数据)但继续处理。我考虑的具体情况是,我希望提供缓存数据,然后如果缓存已过期,我仍会提供缓存数据以获得快速响应,关闭连接,但继续处理以重新生成和缓存新数据。本质上,唯一的目的是让网站看起来更具响应性,因为当用户等待内容重新生成时,不会出现偶尔的延迟 更新: 加上有最接近的答案,我一直在寻找。为了向一些人澄清,我正在寻找能够实现以下步骤的东西: 用户请求页面 连接打开到服务器 PHP检查缓存是否已过期,如果仍然是新的,则提供缓存并关
这很重要,它必须是一个纯粹的PHP解决方案。安装其他软件不是一个选项。PHP没有这种持久性(默认情况下)。我能想到的唯一方法是运行CRON Job来预先填充缓存。 < P>如果您这样做是为了缓存内容,您可能需要考虑使用现有的缓存解决方案,例如.< /p> ,可以通过设置时间限制为无限,忽略连接来实现。
<?php
ignore_user_abort(true);
set_time_limit(0);
否。就Web服务器而言,来自浏览器的请求由PHP引擎处理,仅此而已。请求的持续时间与PHP相同
您可能能够fork()
。可以从PHP-CLI编译和运行程序(不在共享主机>VPS上)
缓存
因为缓存,我不会那样做。我会使用redis作为我的浏览器。尤其是当您使用编译它时
脱机处理
安装消息队列时,还可以执行延迟放置。但是我会使用redis/来完成另一个消息队列部分,因为redis会更快,特别是如果您使用PHP客户机库(在C用户空间中)
无法从PHP-CLI编译或运行程序(在共享主机上)
设置时间限制
大多数情况下,在共享主机上至少设置0是不可用的(因为安全模式或max\u execution\u time
指令)。此外,共享主机提供商不希望用户长时间占用PHP进程。大多数情况下,默认限制设置为30
克朗
使用cron将数据写入光盘。一些stackoverflow主题已经解释了这一点:
也很简单,但还是很粗糙。我认为你应该升级(>VPS)当你必须这样做黑客
异步请求
最后,您可以使用Cache_lite缓存数据请注意共享主机不喜欢占用大量长时间运行的PHP进程。我只使用一个后台进程,当它达到max execution time
指令时调用另一个后台进程。我会记录脚本启动的时间和两个缓存调用之间的时间,我会测量所花费的时间,以及当它接近我执行另一个异步请求的时间。我将使用来确保只有一个进程正在运行。这样我就不会尿的供应商,它可以做到。另一方面,我不认为我会写这篇文章,因为如果你问我的话,这篇文章有点粗糙。当我达到这个规模时,我会升级到VPS。我终于找到了一个解决方案(多亏了谷歌,我不得不不断尝试不同的搜索词组合)。多亏了arr1上的评论(这大约是整个页面的三分之二)
如果在fastcgi下运行,您可以使用非常漂亮的:
fastcgi_完成_请求()
更详细的信息是可用的。据我所知,除非您正在运行FastCGI,否则您无法断开连接并继续执行(除非您得到了内切黑格的工作答案,我失败了)。因此,您可以:
使用cron或类似的工具来安排此类任务
使用子进程完成作业
但情况变得更糟了。即使您使用proc\u open()
生成子进程,PHP也会在关闭连接之前等待它完成,即使在调用exit()
,die()
,一些未定义的函数导致致命错误()。我发现的唯一解决方法是生成一个子进程,该子进程本身会生成一个子进程,如下所示:
function doInBackground ($_variables, $_code)
{
proc_open (
'php -r ' .
escapeshellarg ("if (pcntl_fork() === 0) { extract (unserialize (\$argv [1])); $_code }") .
' ' . escapeshellarg (serialize ($_variables)),
array(), $pipes
);
}
$message = 'Hello world!';
$filename = tempnam (sys_get_temp_dir(), 'php_test_workaround');
$delay = 10;
doInBackground (compact ('message', 'filename', 'delay'), <<< 'THE_NOWDOC_STRING'
// Your actual code goes here:
sleep ($delay);
file_put_contents ($filename, $message);
THE_NOWDOC_STRING
);
函数doInBackground($\u变量,$\u代码)
{
程序打开(
“php-r”。
escapeshellarg(“if(pcntl_fork()==0){extract(unserialize(\$argv[1]);$_code}”)。
''.escapeshellarg(序列化($_变量)),
数组(),$pipes
);
}
$message='helloworld!';
$filename=tempnam(sys_get_temp_dir(),'php_test_workaround');
$delay=10;
doInBackground(compact('message','filename','delay'),关闭连接意味着HTTP或MySQL?@powtac HTTP。我始终可以重新打开MySQL连接。我希望脚本继续运行(短时间和有限时间)在HTTP连接关闭后。大多数情况下,至少在共享主机上,此设置时间限制不可用于设置0。另一方面,共享主机提供商不希望用户长时间占用PHP进程。你是对的,但我认为这是实现内噬所需+1的唯一方法,但也是值得的更值得一提的是,PHP通常会忽略用户中止。@Alfred我不在共享主机上,但仍有一些限制。我知道我可以设置时间限制(0),并且缓存相当快,生成和缓存大约需要半秒,我只是试图避免在用户获得
function doInBackground ($_variables, $_code)
{
proc_open (
'php -r ' .
escapeshellarg ("if (pcntl_fork() === 0) { extract (unserialize (\$argv [1])); $_code }") .
' ' . escapeshellarg (serialize ($_variables)),
array(), $pipes
);
}
$message = 'Hello world!';
$filename = tempnam (sys_get_temp_dir(), 'php_test_workaround');
$delay = 10;
doInBackground (compact ('message', 'filename', 'delay'), <<< 'THE_NOWDOC_STRING'
// Your actual code goes here:
sleep ($delay);
file_put_contents ($filename, $message);
THE_NOWDOC_STRING
);