首頁 >後端開發 >php教程 >curl - php不裝擴充如何實現非同步操作

curl - php不裝擴充如何實現非同步操作

WBOY
WBOY原創
2016-08-18 09:15:541372瀏覽

在我收到請求處理後有一個很耗時的需要請求微信介面的操作,需要處理很多訂單呼叫微信介面。想在echo之後再執行這些操作。訊息佇列需要為伺服器安裝擴充功能如memcacheq之類的,我沒有操作伺服器的權利,想用程式碼解決。可不可以實現訊息佇列,有沒有大神給個例子我對隊列操作一竅不通。我看到了也可以用fsockopen 實現,這樣跟訊息佇列機制有什麼差別。

回覆內容:

在我收到請求處理後有一個很耗時的需要請求微信介面的操作,需要處理很多訂單呼叫微信介面。想在echo之後再執行這些操作。訊息佇列需要為伺服器安裝擴充功能如memcacheq之類的,我沒有操作伺服器的權利,想用程式碼解決。可不可以實現訊息佇列,有沒有大神給個例子我對隊列操作一竅不通。我看到了也可以用fsockopen 實現,這樣跟訊息佇列機制有什麼差別。

<code>//程序被阻塞10秒
shell_exec('timeout 10 vmstat 1 >/dev/null 2>&1 &');
//程序不会被阻塞
pclose(popen('timeout 10 vmstat 1 >/dev/null 2>&1 &', 'r'));
//因此可以异步执行任务
pclose(popen("timeout 60 php /path/to/task.php '$arg' >/dev/null 2>&1 &", 'r'));
</code>

其中變數$arg是傳遞給腳本task.php的參數,task.php裡透過$argv[1]拿到這個參數.
timeout 60 表示task.php腳本的最大執行時間60秒,不需要的話可以去掉.
pclose(popen())實現異步的本質是打開一個進程去執行阻塞代碼,
適用於不要求執行完成後自動返回結果(回調)的異步場景.

字串參數$arg可以用單引號括起來,可以避免一些空格的影響,但還是有缺陷.
為了避免Shell注入(對比SQL注入),字串參數最好還是serialize序列化到文件,
然後給腳本task.php傳檔路徑這個參數,讓task.php自己讀檔案unserialize反序列化拿資料.
檔名應該做到唯一,例如可以是使用者ID+行程PID+時間隨機數:

<code>$filename = md5(uniqid($uid.'_'.getmypid().'_'.mt_rand().'_', true));
</code>

PHP-FPM提供的函數fastcgi_finish_request可以沖刷(flush)所有回應的資料給客戶端並結束請求.這使得客戶端結束連線後,能夠繼續執行不需要輸出給使用者的程式碼,例如產生快取,但仍會阻塞目前FPM工作流程.
http://php.net/manual/zh/func...

fsockopen 意思是發出一個請求(類似curl),但不等待回傳結果。

所以用fsockopen 也可以,你echo之後fsockopen 請求一下本地上對微信介面的操作,就可以了

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn