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'null1);
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) 执行结果

看下图,发现了木有,主程序在被调用脚本之前执行完成了。就是说主程序没有等待被调用脚本执行完成就已经执行完成了。

php实现异步调用

https://gitee.com/Hollis163com/phpasync.git


本文完!


文章有不足之处,请小伙伴们多多留言指正。喜欢老湿文章的小伙伴请多多点赞和评论哦~

↓↓点击【阅读原文】查看源代码

以上是关于php实现异步调用的主要内容,如果未能解决你的问题,请参考以下文章

php实现异步调用

如何延迟或异步此 WordPress javascript 片段以最后加载以加快页面加载时间?

PHP实现异步调用方法研究

php 一个自定义的try..catch包装器代码片段,用于执行模型函数,使其成为一个单行函数调用

异步 celery 任务完成后自动调用 PHP 代码(celery-php)

PHP中实现异步调用多线程程序代码