PHP 两个函数

1 fastcgi_finish_request()
可用PHP版本: php5.3.3,PHP 7,这个函数也适合在CLI模式下运行。
作用:冲刷所有响应的数据给客户端,并结束请求。这可以让客户端在结束连接后,执行一些需要大量时间运行的任务能够继续运行。
返回值: 成功时返回TRUE,失败时返回FALSE
<?php
echo '你看的见我。';
fastcgi_finish_request(); /* 响应完成, 关闭连接 */
echo '你看不见我,看不见我。';
/* 记录日志 */
file_put_contents('log.txt', '生存还是毁灭,这是个问题.');
浏览器运行的话,可以看到“你看的见我:”,但是看不到“你看不见我,看不见我”,可见魔法生效了。运行之后生成了相关文件。
由此说明在调用fastcgi_finish_request后,客户端响应就已经结束,但与此同时服务端脚本却继续运行!注意这个函数,虽然结束了客户端连接,但是运行时间依然会手max_execution_time 超时时间影响。
好处有了,快速的响应客户端,提高用户体验。那他是怎么做的?
追踪一下调用栈
sudo strace -T -tt -e trace=all -p 51263
里面有一行
18:16:07.427611 shutdown(4, SHUT_WR) = 0 <0.000252>
C语言的这个shutdown函数,是用来优雅的断开连接的。shutdown() 用来关闭连接,而不是套接字,不管调用多少次 shutdown(),套接字依然存在,直到调用 close() / closesocket() 将套接字从内存清除。shutdown() 会等输出缓冲区中的数据传输完毕再发送FIN包
使用方法为 shutdown(int socket, int howto),
第一个参数为要断开的套接字。
第二个参数为断开的方式,分别有以下三种(linux系统上)
SHUT_WR:断开输出流。套接字无法发送数据,但如果输出缓冲区中还有未传输的数据,则将传递到目标主机。
事物都有两面性,在运行完函数fastcgi_finish_request后,虽然结束了客户端的请求,但是仍然需要占用php-fpm进程处理后续任务,如果任务特别耗时,这样就会带来一个问题,php-fpm进程都被占用,当请求再次到来的时候,就会出现网关错误(502错误)。
2 register_shutdown_function();
可用版本 php4,php5,php7 注册一个会在php中止时执行的函数。
register_shutdown_function(callback, $parameter)
参数1 代注册的中止回调方法,中止回调是作为请求的一部分被执行的,因此可以在它们中进行输出或者读取输出缓冲区。
第二个参数$parameter
可以通过传入额外的参数来将参数传给中止函数
此函数没有返回值
发生中止有三种情况:
1 脚本执行完毕
2 exit() 和die()
3 发生致命错误
例如
function endit($a){
echo $a;
}
register_shutdown_function('endit', 'sth is wrong');
function endit2($b){
echo $b;
}
register_shutdown_function('endit2', 'sth is wrong2');
直接运行在浏览器里 会出现 sth is wrong sth is wrong2
如果在endit 里有die(); 有exit(); 那么endit2 就不会被顺序执行了.
使用场景:在结束的时候做点什么,记录日志,发短信,发消息,代码是否正常执行完。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注