比如說(shuō)需要做一個(gè)批量發(fā)送手機(jī)短信的功能,如果是用for循壞這樣的來(lái)做的話,當(dāng)短信數(shù)量很大時(shí),不僅耗時(shí),而且成功率很低。
於是想到,用PHP和MySQL實(shí)作一個(gè)訊息佇列,一則的發(fā)送簡(jiǎn)訊。
首先,建立一個(gè)資料表sms,包含以下欄位:
id,
phone, //手機(jī)號(hào)碼
content //簡(jiǎn)訊內(nèi)容
將需要傳送的簡(jiǎn)訊和手機(jī)號(hào)碼存入sms表中。
實(shí)作的程式碼如下:
<?php
while(true){
$item = $db->getFirstRecord(); //獲取數(shù)據(jù)表第一條記錄
if(!$item){//如果隊(duì)列中沒有數(shù)據(jù),則結(jié)束定時(shí)器
break;
}
$res = $sms->send($item['phone'],$item['content']); //發(fā)送短信
if($res){
$db->deleteFristRecord(); //刪除發(fā)送成功的記錄
echo $item['phone'].'發(fā)送成功';
}else{
echo $item['phone'].'發(fā)送失敗,稍后繼續(xù)嘗試';
}
sleep(10); //每隔十秒循環(huán)一次
}
echo '寄完畢! ';
?>
比如說(shuō),後臺(tái)有一個(gè)發(fā)送按鈕,點(diǎn)擊觸發(fā)上面的程式執(zhí)行,假設(shè)每隔10秒從資料庫(kù)取一封資料發(fā)送簡(jiǎn)訊。
問題:如果我點(diǎn)擊發(fā)送按鈕後就直接點(diǎn)擊其他頁(yè)面做其他的去了,而不是一直在點(diǎn)擊頁(yè)面等待直到發(fā)送完畢才離開的話,上面的程式還會(huì)執(zhí)行下去了。還是說(shuō)我去到其他頁(yè)面內(nèi)了,就會(huì)跳出循壞不會(huì)執(zhí)行發(fā)送短信了
PHP是單線程,也就是你一開始執(zhí)行,要嘛等它全部執(zhí)行完畢,要嘛提前中斷,不能同時(shí)進(jìn)行兩個(gè)訪問。如果說(shuō)需要點(diǎn)擊按鈕之後非同步處理,直接跳過去幹別的事情,那就需要swoole這個(gè)服務(wù)來(lái)處理你要非同步處理的事情。
這種情況,直接在命令列模式運(yùn)行就好了,不用放在後臺(tái)網(wǎng)頁(yè)上。然後最上面沒有資料就退出的程式碼,改為sleep一段時(shí)間。
PHP-Cli模式你可以看一下。慕課網(wǎng)有視頻,mysql模擬隊(duì)列發(fā)送郵件,和題主要的效果類似。
我覺的樓主的php+mysql沒錯(cuò),但是cron job還是要用上的。 cron job就是設(shè)定間隔XX秒執(zhí)行一下腳本。
如果非要放棄crontab。那麼推薦下面程式碼
ignore_user_abort() //關(guān)掉瀏覽器,php腳本可以繼續(xù)執(zhí)行
set_time_limit(0) // 一直執(zhí)行下去
$item = $db->getFirstRecord(); //獲取數(shù)據(jù)表第一條記錄
if(!$item){//如果隊(duì)列中沒有數(shù)據(jù),則結(jié)束定時(shí)器
break;
}
$res = $sms->send($item['phone'],$item['content']); //發(fā)送短信
if($res){
$db->deleteFristRecord(); //刪除發(fā)送成功的記錄
echo $item['phone'].'發(fā)送成功';
}else{
echo $item['phone'].'發(fā)送失敗,稍后繼續(xù)嘗試';
}
sleep(10); //每隔十秒循環(huán)一次