前言
客户端与服务器端是通过 HTTP 协议
进行连接通讯,客户端发起请求,服务器端接收到请求,服务端再执行处理,并返回处理结果。
有时服务器需要执行很耗时的操作,这个操作的结果并不需要立即返回给客户端。但因为 php
是同步执行的,所以客户端需要等待一项操作处理完才可以进行下一步操作。
因此,对于耗时的操作适合异步执行。服务器接收到请求后,处理完客户端需要的数据就立即返回,再异步在服务器执行耗时的操作。
使用 Ajax
在服务器返回的页面中插入 Ajax
代码实现异步执行。
$.get('do.php' , { name: 'fdipzone' } );
使用 <img>
标记
在服务器返回的页面中插入 <img>
标签,将 src
参数设定为需要异步执行的操作。
<img src="do.php">
使用 fsockopen
fsockopen
是 PHP
异步执行最好的选择,此函数的功能为初始化一个套接字连接到指定主机,默认情况下将以阻塞模式开启套接字连接。当然你可以通过stream_set_blocking()将它转换到非阻塞模式。这是关键。所以,思路就是开启一个非阻塞的套接字连接到本机,本机收到之后作一些耗时处理。
$fp = fsockopen($php_Path,80);
if (!$fp) {
LMLog::error("fsockopen:err" );
} else {
$out = "GET /album/action/album_write_friends_thread_record.php?key=&u= HTTP/1.1\r\n";
$out .= "Host: ".$php_Path."\r\n";
$out .= "Connection: Close\r\n\r\n";
stream_set_blocking($fp,true);
stream_set_timeout($fp,1);
fwrite($fp, $out);
usleep(1000); //这里非常关键,它能保证这个请求能发出去
fclose($fp);
}
使用 popen
如果要实现多进程的功能,毫无疑问我们会选择官方提供的 pcntl
扩展, PHP
默认会安装 pcntl
扩展,如果代码运行提示找不到 pcntl
扩展,可自行到 php-src 下载,选择好版本安装即可。
<?php
class Arrow{
static $instance;
/**
* @return static
*/
public static function getInstance(){
if (null == Arrow::$instance)
Arrow::$instance = new Arrow();
return Arrow::$instance;
}
public function run($rb){
$pid = pcntl_fork();
if($pid > 0){
pcntl_wait($status);
}elseif($pid == 0){
$cid = pcntl_fork();
if($cid > 0){
exit();
}elseif($cid == 0){
$rb();
}else{
exit();
}
}else
{
exit();
}
}
}
$time_out = 30;
Arrow::getInstance()->run(function() use ($time_out){
//这里写我们要执行的代码
sleep($time_out);
});
评论 (0)