php实现异步调用
Posted 有解php
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php实现异步调用相关的知识,希望对你有一定的参考价值。
文章简介
本文提供php实现异步调用php脚本的两个方案和实例源码。
异步执行
异步执行是无需得到被调用脚本的返回值,就让主操作继续往下执行的方法。打个比方,一群人在一起做烧烤,这个时候发现啤酒没买,于是让小明去买啤酒,其他人继续做烤串,而不需要等小明买完啤酒回来再继续做烤串。这种情景下的大家做烧烤和小明买啤酒的操作就是异步执行的。
使用场景
当一个脚本需要执行一系列的操作,但是有一些操作比较耗时,就可以把这些耗时操作放在其他的脚本中,在主程序中用异步的方式调用这些耗时的脚本。这样就可以让主程序和这些耗时操作一起执行,因此不会使主程序后面的一系列操作因这些耗时操作而等待过久。
代码实例:
(1) 目录结构
(2) 方案1代码:main_curl.php
curl方式实现异步调用do_other.php脚本
/*
* curl方式实现异步调用php脚本
*/
function _curl($url, $data = null, $timeout = 1)
{
$curl = curl_init();
//调用doOther.php脚本执行一些其他操作
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
if ($timeout > 0) { //超时时间秒
curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
}
$output = curl_exec($curl);
$error = curl_errno($curl);
curl_close($curl);
if ($error) {
return false;
}
return $output;
}
//这里的url是被调用脚本的url
$output = _curl('http://youjiephp.test.com/phpasync/do_other.php', null, 1);
echo '主脚本执行完成'.date('Y-m-d H:i:s');
(3) 方案2代码:main_fsockopen.php
fsockopen方式实现异步调用do_other.php脚本
/*
* fsockopen实现异步调用php脚本
*/
function _fsockopen($url, $post_data = array(), $cookie = array())
{
$url_arr = parse_url($url);
$port = isset($url_arr['port']) ? $url_arr['port'] : 80;
if ($url_arr['scheme'] == 'https') {
$url_arr['host'] = 'ssl://' . $url_arr['host'];
}
$fp = fsockopen($url_arr['host'], $port, $errno, $errstr, 30);
if (!$fp) return false;
$getPath = isset($url_arr['path']) ? $url_arr['path'] : '/index.php';
$getPath .= isset($url_arr['query']) ? '?' . $url_arr['query'] : '';
$method = 'GET'; //默认get方式
if (!empty($post_data)) $method = 'POST';
$header = "$method $getPath HTTP/1.1
";
$header .= "Host: " . $url_arr['host'] . "
";
if (!empty($cookie)) { //传递cookie信息
$_cookie = strval(NULL);
foreach ($cookie AS $k => $v) {
$_cookie .= $k . "=" . $v . ";";
}
$cookie_str = "Cookie:" . base64_encode($_cookie) . "
";
$header .= $cookie_str;
}
if (!empty($post_data)) { //传递post数据
$_post = array();
foreach ($post_data AS $_k => $_v) {
$_post[] = $_k . "=" . urlencode($_v);
}
$_post = implode('&', $_post);
$post_str = "Content-Type:application/x-www-form-urlencoded; charset=UTF-8
";
$post_str .= "Content-Length: " . strlen($_post) . "
"; //数据长度
$post_str .= "Connection:Close
";
$post_str .= $_post; //传递post数据
$header .= $post_str;
} else {
$header .= "Connection:Close
";
}
fwrite($fp, $header);
usleep(1000); // 这一句也是关键,如果没有这延时,可能在nginx服务器上就无法执行成功
fclose($fp);
return true;
}
//这里的url是被调用脚本的url
_fsockopen('http://youjiephp.test.com/phpasync/do_other.php');
echo '主脚本执行完成'.date('Y-m-d H:i:s');
(4) 被调用脚本代码:do_other.php
try{
//为了验证异步执行(即此脚本没执行完,主脚本已执行完),此处等待10秒
sleep(10);
//向note.txt写执行记录
file_put_contents('./note.txt','执行耗时操作'.date('Y-m-d H:i:s')."
",FILE_APPEND);
}catch (Exception $e){
echo $e->getMessage();
}
(5) 执行结果
看下图,发现了木有,主程序在被调用脚本之前执行完成了。就是说主程序没有等待被调用脚本执行完成就已经执行完成了。
https://gitee.com/Hollis163com/phpasync.git
本文完!
文章有不足之处,请小伙伴们多多留言指正。喜欢老湿文章的小伙伴请多多点赞和评论哦~
↓↓↓点击【阅读原文】查看源代码
以上是关于php实现异步调用的主要内容,如果未能解决你的问题,请参考以下文章
如何延迟或异步此 WordPress javascript 片段以最后加载以加快页面加载时间?
php 一个自定义的try..catch包装器代码片段,用于执行模型函数,使其成为一个单行函数调用