php 不等待返回的實現方法(非同步呼叫)

2022-08-27 17:54:13 字數 3177 閱讀 2781

php非同步執行的常用方式常見的有以下幾種,可以根據各自優缺點進行選擇:

1.客戶端頁面採用ajax技術請求伺服器

優點:最簡單,也最快,就是在返回給客戶端的html**中,嵌入ajax呼叫,或者,嵌入乙個img標籤,src指向要執行的耗時指令碼。

缺點:一般來說ajax都應該在onload以後觸發,也就是說,使用者點開頁面後,就關閉,那就不會觸發我們的後台指令碼了。

而使用img標籤的話,這種方式不能稱為嚴格意義上的非同步執行。使用者瀏覽器會長時間等待php指令碼的執行完成,也就是使用者瀏覽器的狀態列一直顯示還在load。

當然,還可以使用其他的類似原理的方法,比如script標籤等等。

2.popen()函式

該函式開啟乙個指向程序的管道,該程序由派生給定的 command 命令執行而產生。開啟乙個指向程序的管道,該程序由派生給定的 command 命令執行而產生。

所以可以通過呼叫它,但忽略它的輸出。使用**如下:

pclose(popen("/home/xinchen/backend.php &",'r'));

優點:避免了第乙個方法的缺點,並且也很快。

缺點:這種方法不能通過http協議請求另外的乙個webservice,只能執行本地的指令碼檔案。並且只能單向開啟,無法穿大量引數給被呼叫指令碼。並且如果,訪問量很高的時候,會產生大量的程序。如果使用到了外部資源,還要自己考慮競爭。

3.curl擴充套件

curl是乙個強大的http命令列工具,可以模擬post/get等http請求,然後得到和提取資料,顯示在"標準輸出"(stdout)上面。**如下:

$ch =curl_init();

$curl_opt =array(curlopt_url,'',

curlopt_returntransfer,1,

curlopt_timeout,1,);

curl_setopt_array($ch,$curl_opt);

curl_exec($ch);

curl_close($ch);

缺點如你問題中描述的一樣,由於使用curl需要設定curopt_timeout為1(最小為1,鬱悶)。也就是說,客戶端至少必須等待1秒鐘。

4.fscokopen()函式

fsockopen支援socket程式設計,可以使用fsockopen實現郵件傳送等socket程式等等,使用fcockopen需要自己手動拼接出header部分

可以參考: 

使用示例如下:

$fp =fsockopen("www.34ways.com",80,$errno,$errstr,30);

if(!$fp)else*/

fclose($fp);

}所以總結來說,fscokopen()函式應該可以滿足您的要求。可以嘗試一下。

php 本身沒有多執行緒的東西,但可以曲線的辦法來造就出同樣的效果,比如多程序的方式來達到非同步呼叫,只限於命令模式。還有一種更簡單的方式,可用於 web 程式中,那就是用fsockopen()、fputs()來請求乙個 url 而無需等待返回,如果你在那個被請求的頁面中做些事情就相當於非同步了。

關鍵**如下:

$fp=fsockopen('localhost',80,&$errno,&$errstr,5);

if(!$fp)

fputs($fp,"get another_page.php?flag=1\r\n");

fclose($fp);

上面的**向頁面 another_page.php 傳送完請求就不管了,用不著等待請求頁面的響應資料,利用這一點就可以在被請求的頁面 another_page.php 中非同步的做些事情了。

比如,乙個很切實的應用,某個 blog 在每 post 了一篇新日誌後需要給所有它的訂閱者發個郵件通知。如果按照通常的方式就是:

日誌寫完 -> 點提交按鈕 -> 日誌插入到資料庫 -> 傳送郵件通知 ->

告知撰寫者發布成功

那麼作者在點提交按鈕到看到成功提示之間可能會等待很常時間,基本是在等郵件傳送的過程,比如連線郵件服務異常、或器緩慢或是訂閱者太多。而實際上是不管郵件傳送成功與否,保證日誌儲存成功基本可接受的,所以等待郵件傳送的過程是很不經濟的,這個過程可非同步來執行,並且郵件傳送的結果不太關心或以日誌形式記錄備查。

改進後的流程就是:

日誌寫完 -> 點提交按鈕 -> 日誌插入到資料庫 --->

告知撰寫者發布成功

└ 傳送郵件通知 -> [記下日誌]

用個實際的程式來測試一下,有兩個 php,分別是 write.php 和 sendmail.php,在 sendmail.php 用 sleep(seconds) 來模擬程式執行使用時間。

write.php,執行耗時 1 秒

<?php

functionasyn_sendmail()

sleep(1);

fputs($fp,"get /sendmail.php?param=1\r\n");#請求的資源 url 一定要寫對

fclose($fp);

}echo time().'

';echo 'call asyn_sendmail

';asyn_sendmail();

echo time().'

';?>

sendmail.php,執行耗時 10 秒

<?php

//sendmail();

//sleep 10 seconds

sleep(10);

fopen('c:\'.time(),'w');

?>

通過頁面訪問 write.php,頁面輸出:

1272472697 call asyn_sendmail

1272472698

並且在 c:\ 生成檔案:

從上面的結果可知 sendmail.php 花費至少 10 秒,但不會阻塞到 write.php 的繼續往下執行,表明這一過程是非同步的。

php非同步實現,避免長時間等待

處理的php非同步的方法有好幾種,這裡我就只介紹我經常用的而且官方也推薦的 廢話少說,直接貼 php非同步 public function dorequest host,path,param array 呼叫例項 我這裡值介紹post方式,get方便那麼簡單就不介紹了,一樣的 引數說明 引數1 請求...

php處理非同步請求 PHP實現非同步呼叫方法研究

瀏覽器和伺服器之間是通過 http 協議進行連線通訊的。這是一種基於請求和響應模型的協議。瀏覽器通過 url 向伺服器發起請求,web 伺服器接收到請求,執行一段程式,然後做出響應,傳送相應的html 給客戶端。這就有了乙個問題,web 伺服器執行一段程式,可能幾毫秒就完成,也可能幾分鐘都完不成。如...

PHP程式設計實現指令碼非同步執行的方法

php語言得用fsockopen 函式,實現指令碼非同步執行,如下 非同步請求函式 用debug引數若為true則為用為除錯,開啟除錯可以看到非同步的執 況,但是失去非同步的效果 main.php method get if empt程式設計客棧y post data 程式設計客棧 header m...