關於PHP的異步調用


眾所周知,PHP沒有多線程這種東西,雖然也可以實現異步,但都是用一些折中的方法來做到的。

總結一下自己這幾天接觸到的PHP異步調用需求和解決方法。

當然,自己是個偽碼農,使用的方法,都是些極端不優雅的笨方法,還有待總結修正提高。

 

一、一個專利采集分析的系統,需要一個完整的操作界面,一個采集進度的動態進度條。(AJAX)

用AJAX來實現,通過ajax不停地訪問服務器,,通過setInterval來設置間隔時間,訪問backend.php文件,獲得已經采集的數量,然后更新頁面相應DOM的內容即可。

jQuery學得不太好,代碼比較丑陋,demo如下:

 1 jQuery(document).ready(function($) { 
 2     
 3     $('#submit').click(function(){ 
 4         setInterval("updateMsg()", 1000); 
 5         $.post('total.php', $('#form1').serialize(), function(data, textStatus){ 
 6             var new_data = "<p>本次所要采集的專利總數為:" + data + "</p>"; 
 7             $('#total_area').html(new_data); 
 8             $('#monitor_area').html('<p>正在初始化信息監控.....</p>'); 
 9         }); 
10         $.post('test.php',$('#form1').serialize()); 
11         return false; 
12     });
13 
14 function updateMsg(){ 
15         $.get("backend.php",{},function(data, textStatus){ 
16             var now_total = "<p>目前已采集數量:" + data + "</p>"; 
17             $("#monitor_area").html(now_total); 
18         }); 
19 }

 

 

二、一個郵件發送提醒的應用。(消息隊列)

一個報名系統,想在第一時間知道報名者的信息並與其取得聯系,並發極低,可能十多天就那么一條報名信息。

手機提醒用了發郵件到139的方法。

但是有一個問題,就是將發郵件的代碼寫到用戶提交個人信息的程序段里以后,提交的過程會變得非常慢,可能達到3S多,簡直無法忍受。

對於郵件發送這種耗時很長的東西,采用了“隊列”的方法。當然,這個隊列沒有RabbitMQ和ZeroMQ這種東西這么高級,其實就是將信息存到數據庫里,算作是入隊列了,然后設置一個cron來處理數據庫里的這些信息,處理了,也就是出隊列的,這也是個笨辦法了。

 

三、那些聽說過沒有用過的高級方法

1.自然就是到處都是的消息隊列了,自己用數據庫模擬的,只不過是最低端的方法而已,不是針對並發的,若是面對高並發,必然會掛掉。這個時候,用上傳說中的RabbitMQ這些東西,性能應該有極大的提升。還有就是Redis數據庫,用過這個東西,感覺用它的list來做消息隊列,應該也是非常棒的。

2.CURL的方法,curl_multi據說也是個好東西,但是由於CUROPT_TIMEOUT最小是1,所以客戶端至少要等待1S,這也是硬傷。

3.popen()函數,打開一個指向進程的管道,該進程由派生給定的 command 命令執行而產生。

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

 

 

4.fsockopen()方法,這個方法要自己拼接處http頭來才行。

5.PHP多進程,其實這個方法自己用過,就是將要處理的大段數據按照for循環,用vim處理分成小段,然后在CLI模式下跑

php –f example1.php &

php –f example2.php &

用這種笨辦法將PHP的進程放到后台來執行……

后來才知道,原來PHP在*uinx下可以直接pcntl類似於C那樣fork出進程來,才知道了這個方法,在采集數據的時候,挺好用的,配合CURL和fsockopen,速度飛快。可惜,可惜的是,剛爽了一會,然后IP就被封掉了……

這個的處理,還是很方便的。

 1  for($i = 0; $i <$intNum; $i++) {
 2      $pids[$i] = pcntl_fork();// 產生子進程,而且從當前行之下開試運行代碼,而且不繼承父進程的數據信息
 3      if($pids[$i] == -1) {
 4          echo "couldn't fork". "\n";
 5       } elseif(!$pids[$i]) {
 6      sleep(1);
 7      echo "\n"."第".$i."個進程 -> " . time(). "\n";
 8     //這里就可以放信息采集抓取等東西的代碼了。
 9      exit(0);//子進程要exit否則會進行遞歸多進程,父進程不要exit否則終止多進程
10  }
11 }

 

6.gearman分布式計算,開很多的worker來支持將job分布到不同機器上去執行,這個,自己接觸不到,傳說中了。

參考的那些資料:

1.當然是鳥哥的博客了,風雪之隅,這幾種異步方法都是在他那兒看到的。

2.張宴的博客,多進程的內容。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM