溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

PHP同步和異步的區(qū)別以及fsockopen異步的操作

發(fā)布時間:2021-09-03 19:36:37 來源:億速云 閱讀:207 作者:chen 欄目:大數(shù)據(jù)

這篇文章主要介紹“PHP同步和異步的區(qū)別以及fsockopen異步的操作”,在日常操作中,相信很多人在PHP同步和異步的區(qū)別以及fsockopen異步的操作問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”PHP同步和異步的區(qū)別以及fsockopen異步的操作”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

一、同步與異步的區(qū)別:

  1、同步模式:后一個任務(wù)等待前一個任務(wù)結(jié)束,然后再執(zhí)行,程序的執(zhí)行順序與任務(wù)的排列順序是一致的、同步的.

  2、異步模式:則完全不同,每一個任務(wù)有一個或多個回調(diào)函數(shù)(callback),前一個任務(wù)結(jié)束后,不是執(zhí)行后一個任務(wù),而是執(zhí)行回調(diào)函數(shù),后一個任務(wù)則是不等前一個任務(wù)結(jié)束就執(zhí)行,所以程序的執(zhí)行順序與任務(wù)的排列順序是不一致的、異步的。 "異步模式"非常重要。在瀏覽器端,耗時很長的操作都應(yīng)該異步執(zhí)行,避免瀏覽器失去響應(yīng),就現(xiàn)在來說應(yīng)該沒有什么后臺服務(wù)器還是同步操作了

舉一個場景:在用戶搶票的時候,并不希望用戶排隊(duì)去連接數(shù)據(jù)庫進(jìn)行查詢、判斷、插入,完成之后再返回用戶結(jié)果。其實(shí)我們并不需要用戶等那么久的時間,用戶提交之后,直接告訴他已經(jīng)搶票成功了就可以了,至于各種操作,交給后臺去處理就好。當(dāng)然,這種情況我們現(xiàn)在都用消息列表來處理,把每一個用戶提交的請求存在一個消息列隊(duì)中,告訴用戶已經(jīng)搞定了,用戶愉快的關(guān)掉頁面之后,實(shí)際上后臺還在一個一個從消息列隊(duì)中取出請求進(jìn)行操作。我們這篇文章則是通過一種異類的手法,實(shí)現(xiàn)操作在后臺運(yùn)行,無需用戶等待。

二、fsockopen異步

  對于php來說最大缺點(diǎn)就是無法實(shí)現(xiàn)多線程管理,其程序的執(zhí)行都是從頭到尾,按照邏輯一路執(zhí)行下來,不可能出現(xiàn)分支,

  1、創(chuàng)建需要操作耗時方法

//循環(huán)操作1w次數(shù)據(jù)庫
   public function test(){
       $i=input('id')?input('id'):1;
       while ( $i<= 10000) {
           echo $i;
           echo '<br/>';
           $data = ['title' => $i.'-'.date('Y-m-d H:i:s'), 'num' => $i];
           Db::name('input')->insert($data);
           $i++;
       }
       echo '完成';
   }

      2、我們創(chuàng)建了一個基于fsockopen的函數(shù),這個函數(shù)中利用fsockopen去訪問url,但是在訪問時,并不要求獲取url顯示的內(nèi)容,而是僅僅發(fā)出訪問請求,請求到達(dá)后馬上關(guān)閉這個訪問。這樣做的好處就是無需再等待被訪問的url是否返回了可靠的信息,節(jié)約了時間,這段代碼的執(zhí)行時間在0.1-0.2秒之間,對于普通訪客而言,幾乎察覺不到。因此,在使用時,僅需要調(diào)用這個函數(shù)和對應(yīng)的url即可。不過,這里并沒有提供數(shù)據(jù)傳輸?shù)牟糠?,如何傳輸?shù)據(jù),其實(shí)只需要在$header中增加post的內(nèi)容即可。

  /**
     * @生生 2018/12/24 19:25:06
     * [asynchronous PHP異步執(zhí)行任務(wù)]
     * @param  string $url       執(zhí)行任務(wù)的url地址
     * @param  array  $post_data 需要post提交的數(shù)據(jù)POST
     * @param  array  $cookie    cookie數(shù)據(jù)用于登錄等的設(shè)置(此處內(nèi)部調(diào)用,無需鑒權(quán))
     * @return boole
     */
public function asynchronous($url,$post_data = array())
    {
        $url_array = parse_url($url);
        dump($url_array);
        //用fsockopen()嘗試連接 
        $fp = fsockopen($url_array['host'], 80, $errno, $errstr, 30);
        if (!$fp) {
            echo "$errstr ($errno)<br />\n";
        } else {
            //建立成功后,向服務(wù)器寫入數(shù)據(jù) 
            $getPath = isset($url_array['path']) ? $url_array['path'] : '/';
            $out = "GET /".$getPath."/ HTTP/1.1\r\n";
            $out .= "Host:".$url_array['host']."\r\n";
            $out .= "Connection: Close\r\n\r\n";
          
            fwrite($fp, $out);
            /*忽略執(zhí)行結(jié)果
            while (!feof($fp)) {
                echo fgets($fp, 128);
            }*/
            //關(guān)閉鏈接
            fclose($fp);
        }
    }

  3、創(chuàng)建調(diào)起方法

//調(diào)用方法
function yibu(){
 
    /**
     *  異步方法
     *  參數(shù):(string)要執(zhí)行的方法url,(array)傳入?yún)?shù)
     */
    $this->asynchronous('http://119.23.33.37/index.php/admin/index/test',['1'=>'haha']);
    //直接返回結(jié)果
    echo '操作成功';
}

   4、瀏覽器訪問調(diào)起方法(直接返回操作結(jié)果,大量循環(huán)后臺慢慢執(zhí)行)

PHP同步和異步的區(qū)別以及fsockopen異步的操作

三、swoole異步操作

 1、創(chuàng)建異步服務(wù)器

<?php
//include '../application/admin/controller/SwooleAsynchronous.php';
/**
 * @生生 2018.1.1
 * 創(chuàng)建異步服務(wù)器
 */
$ser = new swoole_server('0.0.0.0',9506);
//設(shè)置進(jìn)程數(shù)
$ser->set(array('task_worker_num'=>4));
 
//當(dāng)有數(shù)據(jù)進(jìn)來的時候
$ser->on('receive',function($ser,$fd,$from_id,$data){
    //投遞異步任務(wù)
    $task_id = $ser->task($data);
    echo "Dispath AsyncTask: id=$task_id\n";
});
 
/**
 * @處理異步任務(wù)
 * 調(diào)用$serv->task()后,程序立即返回,繼續(xù)向下執(zhí)行代碼
 */
$ser->on('task',function($ser,$task_id,$from_id,$data){
    echo "這個是:$task_id".'-'.$data.PHP_EOL;
    //call_user_func('SwooleAsynchronous::huidiao', $value);
    //返回任務(wù)執(zhí)行的結(jié)果
    $ser->finish("任務(wù)完成");
});
 
/**
 * @處理異步任務(wù)的結(jié)果
 * finish操作是可選的,也可以不返回任何結(jié)果
 */
$ser->on('finish', function ($ser,$task_id,$data) {
    sleep(5);
    echo "數(shù)據(jù)是:$data".PHP_EOL;
});
 
//開啟
$ser->start();

 2、執(zhí)行異步(執(zhí)行方法前要引入swoole_client這個類)

public function index(){<br>          //異步處理方法
        $url = url('index/swooletest/test','','','119.23.33.37');
        $params=[
            ['id'=>1,'url'=>$url],
        ];//接口數(shù)據(jù)
        $msg = json_encode($params);
        $client = new swoole_client(SWOOLE_SOCK_TCP);
        //連接到服務(wù)器
        if (!$client->connect('127.0.0.1', 9506, 0.5))
        {
            $this->write("鏈接失敗");
        }
        //向服務(wù)器發(fā)送數(shù)據(jù)
        if (!$client->send($msg))
        {
            $this->write("發(fā)送失敗");
        }
        //關(guān)閉連接
        $client->close();
        echo  '完成';
        //注冊連接成功回調(diào)
        // $client->on("connect", function($cli) {
        //     $cli->send("hello world\n");
        // });
 
        //注冊數(shù)據(jù)接收回調(diào)
        // $client->on("receive", function($cli,$data){
        //     echo "Received: ".$data."\n";
        // });
 
        //注冊連接關(guān)閉回調(diào)
        // $client->on("close", function($cli,$data){
        //     echo "Received: ".$data."\n";
        // });     
    }

訪問index方法,來向服務(wù)端發(fā)送異步任務(wù),這里用send是把需要操作的url發(fā)送過去

到此,關(guān)于“PHP同步和異步的區(qū)別以及fsockopen異步的操作”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

php
AI