眾所周知,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.張宴的博客,多進程的內容。