首页 / PHP学习笔记 / PHP功能模型 / 如何让PHP在后台执行代码,并且无等待直接返回成功状态

如何让PHP在后台执行代码,并且无等待直接返回成功状态

今天在做一个向关注话题用户发送消息的功能。具体功能如下:

当用户对话题进行回复的时候,要求给关注用户发送“您关注的话题有人回复了”的消息。

该功能分两步:

第一步:创建消息,向消息表内插入消息数据。

第二步:向用户消息关系表添加用户和消息的关联数据。这些用户就是关注该话题的用户id。

功能看上去很简单。但是问题是,当前话题关注用户达到一定数量的时候,在插入数据时很耗时间。假设该话题有5000人关注,那么在批量插入的时候后台需要数据插入完成之后才能向前台返回状态。显示这样是不行的,要立马给用户返回状态。接下来就是具体功能的实现过程。

使用PHP的header返回HTTP状态信息

要想客户端立马得到返回信息,需要立马告诉客户端(这里指浏览器)连接关闭了。在此之前要清除缓冲内容,如果不清除缓存,里面可能有之前的HTTP的其他旧信息。导致后面的内容不能及时输出。关闭连接之后,然后发送200的状态码,让浏览器知道请求是成功的。

ob_end_clean();#清除之前的缓冲内容,这是必需的,如果之前的缓存不为空的话,里面可能有http头或者其它内容,导致后面的内容不能及时的输出
header("Connection: close");//告诉浏览器,连接关闭了,这样浏览器就不用等待服务器的响应
header("HTTP/1.1 200 OK"); //可以发送200状态码,以这些请求是成功的,要不然可能浏览器会重试,特别是有代理的情况下

记得在代码执行之前,不要使用return或者die来执行。使用echo 来返回状态值。可以返回json数据。

ob_start();#开始当前代码缓冲
$query = 'INSERT INTO message(message) VALUES';
for($i=0;$i<10000;$i++){
    $query .= '("这是要插入的内容")';
    if($i < 9999){
        $query .= ',';
    }
}
if($query){
    echo json_encode(['state' => true]);
}else{
    echo json_encode(['state' => false]);
}
//下面输出http的一些头信息
$size=ob_get_length();
header("Content-Length: $size");
ob_end_flush();#输出当前缓冲
flush();#输出PHP缓冲

这里其实浏览器已经可以接收到state返回值了。接下来执行mysql插入代码。

ignore_user_abort(true)和set_time_limit(0)

ignore_user_abort()函数告诉设置与客户机断开是否会终止脚本的执行。默认是false:终止继续执行脚本。true:继续执行脚本。因为上面已经关闭浏览器的连接。所以函数bool为true,继续执行后面的代码。

set_time_limit(0)则是取消脚本的超时限制。

ignore_user_abort(true); // 后台运行,这个只是运行浏览器关闭,并不是直接就中止返回200状态。
set_time_limit(0); // 取消脚本运行时间的超时上限
$link = mysqli_connect('localhost','root','123456','test');
$db = mysqli_select_db($link,'test');

$file = fopen('./log.txt','w+');

if(mysqli_query($link,$query)){
    fwrite($file,'插入成功');
}else{
    $e = new Exception();
    fwrite($file,$query);
}

上面就是向表插入数据代码,共插入10000条数据。

当然,实时上如果真要一下子插入10000条数据,mysql压力过大。这里可以使用分批插入的方法。

比如把10000条分10组分别插入到数据库。并且可以对每次插入的数据成功与否做一个记录。

以上就是php在后台执行代码,并且立即返回状态码的方法。

全部代码下载:

php.rar

声明:转载请注明原文地址及作者姓名。 作者:Glary Joker 文章地址://glaryjoker.com/article/387.html

评论

登录后评论.