今天遇到一个东西,一个业务处理的时间比较长,想在处理业务的时候提前返回一些标识给前端,让前端不用等待,不然前端请求的时候一直都会在转圈圈,到一定时间浏览器还会提示说是否关闭,所以就想到ob缓存。
下面是使用代码
ob_end_clean();
ob_start();
echo 123123;//ajax先返回
echo str_repeat(' ' ,100000);//这里输出值超过 nginx配置大小,即缓存输出
$size = ob_get_length();
header("Content-Length: $size");
header("Content-Encoding:none");
header('Connection: close');
header("HTTP/1.1 200 OK");
header("Content-Type: application/json;charset=utf-8");
ob_flush();
flush();
ignore_user_abort(true);//在关闭连接后,继续运行php脚本
set_time_limit(650);
if (function_exists("fastcgi_finish_request")) fastcgi_finish_request(); // 告诉ajax中断连接
//继续运行的代码
sleep(5);
要点有几个,首先是content-encoding这个东西的作用就是告诉浏览器不要经过任何压缩,因为如果nginx配置了gzip压缩是使用不了ob缓存的,我试过用ini_set但是没有任何作用,所以只能用header,还有下面的fastcgi_finish_request(),这个是对于ajax的,告诉ajax中断连接了,不然ajax还是会等上5s,虽然说普通的访问是可以的。
还有一个就是ob_flush和flush,ob_flush这个是让echo的东西从php缓存输出到nginx缓存,flush是通知nginx的缓存输出到浏览器,但是nginx并不是那么听话的,他也有自己的缓存区,你必须够多少我才输出回去,任凭你怎么通知我,我都不做,除非你结束了,所以在最上面的时候str_repeat插入了一大堆空数据,这个根据nginx的缓存区调节,还有一个是set_time_limit这个的作用是告诉php脚本执行的过期时间,单位秒,一般的是30s,如果没有这一句,不管下面sleep多少秒,他最多给你执行30s,然后就强制结束。