PHP异步处理方法

日志 / 107人浏览 / 0人评论

当客户端访问服务端一个api接口,而服务端有时执行一些耗费时间的任务(结果不需要返回客户),由于PHP本身的特性(单线程,同步进行),要等服务端完成任务了才返回结果给客户端。可以先将结果返回给客户端,同时服务端异步执行耗时的任务。

以下有几段代码可以实现异步操作:


function _curl($url,$params) {

  $ch = curl_init();

  $headers = array("Content-type: application/json;charset='utf-8'",

  "Accept: application/json",

  "Cache-Control: no-cache","Pragma: no-cache");

  curl_setopt($ch, CURLOPT_CUSTOMREQUEST,"PUT"); //设置请求方式

  curl_setopt($ch, CURLOPT_POSTFIELDS, $params);//设置提交的字符串

  curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);    //设置头信息

  curl_setopt($ch, CURLOPT_URL, $url); // 要访问的地址

  curl_setopt($ch, CURLOPT_RETURNTRANSFER , 1 );    //获取的信息以文件流的形式返回

  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);  //不进行ssl验证

  curl_setopt($ch, CURLOPT_AUTOREFERER, 1); // 自动设置Referer

  //设置超时时间为1秒,超过1秒则关闭连接

  // curl_setopt($ch,CURLOPT_TIMEOUT,1);     // 超时秒

  curl_setopt($ch, CURLOPT_NOSIGNAL, 1);     //注意,毫秒超时一定要设置这个

  curl_setopt($ch, CURLOPT_TIMEOUT_MS, 200); //超时毫秒,cURL 7.16.2中被加入。从PHP 5.2.3起可使用

  curl_setopt($ch, CURLOPT_HEADER, 0); // 设置是否显示返回头信息  1返回 0不返回

  curl_setopt($ch, CURLOPT_NOBODY, 0); //不想在输出中包含body部分,设置这个选项为一个非零值

  $result = curl_exec($ch);

  curl_close($ch);

  return json_decode($result);

 }



 function syncRequest($url, $param=array(),$postData="",$timeout =10)

 {

  $urlParmas = parse_url($url);

  $host = $urlParmas['host'];

  $path = $urlParmas['path'];

  $scheme = $urlParmas['scheme'];

  $port = isset($urlParmas['port'])? $urlParmas['port'] :80;

  $errno = 0;

  $errstr = '';

  if($scheme == 'https') {

  $host = 'ssl://'.$host;

  }

  $fp = fsockopen($host, $port, $errno, $errstr, $timeout);

  stream_set_blocking($fp,true);//开启了手册上说的非阻塞模式

  $query = isset($param)? http_build_query($param) : '';

  //如果传递参数在body中,则使用

  if(!empty($postData)) $query = $postData;

  $out = "PUT ".$path." HTTP/1.1\r\n";

  $out .= "host:".$host."\r\n";

  $out .= "content-length:".strlen($query)."\r\n";

  //传递参数为url=?p1=1&p2=2的方式,使用application/x-www-form-urlencoded方式

  //$out .= "content-type:application/x-www-form-urlencoded\r\n";

  //传递参数为json字符串的方式,并且在请求体的body中,使用application/json

  $out .= "content-type:application/json\r\n";

  $out .= "connection:close\r\n\r\n";

  $out .= $query;



  fputs($fp, $out);

  $result = "";

  fclose($fp);

 }



 function doRequest($url, $param=array()){



 $urlinfo = parse_url($url);

 var_dump($urlinfo);

 $host = $urlinfo['host'];

 $path = $urlinfo['path'];

 $query = isset($param)? http_build_query($param) : '';



 $port = 80;

 $errno = 0;

 $errstr = '';

 $timeout = 10;



 $fp = fsockopen($host, $port, $errno, $errstr, $timeout);



 $out = "POST ".$path." HTTP/1.1\r\n";

 $out .= "host:".$host."\r\n";

 $out .= "content-length:".strlen($query)."\r\n";

 $out .= "content-type:application/x-www-form-urlencoded\r\n";

 $out .= "connection:close\r\n\r\n";

 $out .= $query;



 fputs($fp, $out);

 fclose($fp);

 }




以上代码经过测试都可以用,注意在_curl()方法中,如果设置毫秒超时,CURLOPT_TIMEOUT_MS 设置太小的话,异步执行操作可能失败(不执行),在测试中设置为150ms,没有问题,但是设置为100ms,异步执行操作失败,但不影响返回结果给客户端

感谢博主,喝杯咖啡~

0 条评论

还没有人发表评论

发表评论 取消回复

记住我的信息,方便下次评论
有人回复时邮件通知我