亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > PHP > 正文

詳解PHP執行定時任務的實現思路

2024-05-04 23:41:11
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了詳解PHP執行定時任務的幾種實現思路,PHP的定時任務功能必須通過和其他工具結合才能實現,們就來深入的解析幾種常見的php定時任務的思路
 

PHP本身是沒有定時功能的,PHP也不能多線程。PHP的定時任務功能必須通過和其他工具結合才能實現,例如WordPress內置了wp-cron的功能,很厲害。

一、Linux服務器上使用CronTab定時執行php

我們先從相對比較復雜的服務器執行php談起。服務器上安裝了php,就可以執行php文件,無論是否安裝了nginx或Apache這樣的服務器環境軟件。而Linux中,使用命令行,用CronTab來定時任務,又是絕佳的選擇,而且也是效率最高的選擇。

首先,進入命令行模式。作為服務器的linux一般都默認進入命令行模式的,當然,我們管理服務器也一般通過putty等工具遠程連接到服務器,為了方便,我們用root用戶登錄。在命令行中鍵入:

crontab -e

之后就會打開一個文件,并且是非編輯狀態,則是vi的編輯界面,通過敲鍵盤上的i,進入編輯模式,就可以編輯內容。這個文件中的每一行就是一個定時任務,我們新建一行,就是新建一條定時任務(當然是指這一行內按照一定的格式進行書寫)。我們現在來舉個例子,增加一行,內容如下:

00 * * * * lynx -dump https://www.yourdomain.com/script.php

這是什么意思呢?實際上上面這一行由兩部分組成,前面一部分是時間,后面一部分是操作內容。例如上面這個,

00 * * * *
就是指當當前時間的分鐘數為00時,執行該定時任務。時間部分由5個時間參數組成,分別是:

分 時 日 月 周
第1列表示分鐘1~59 每分鐘用或者 */1表示,/n表示每n分鐘,例如*/8就是每8分鐘的意思,下面也是類推
第2列表示小時1~23(0表示0點)
第3列表示日期1~31
第4列表示月份1~12
第5列標識號星期0~6(0表示星期天)

整個句子的后面部分就是操作的具體內容。

lynx -dump https://www.yourdomain.com/script.php

意思就是說通過lynx訪問這個url。我們在使用中主要用到lynx、curl、wget來實現對url的遠程訪問,而如果要提高效率,直接用php去執行本地php文件是最佳選擇,例如:

00 */2 * * * /usr/local/bin/php /home/www/script.php

這條語句就可以在每2小時的0分鐘,通過linux內部php環境執行script.php,注意,這里可不是通過url訪問,通過服務器環境來執行哦,而是直接執行,因為繞過了服務器環境,所以效率當然要高很多。

好了,已經添加了幾條需要的定時任務了吧。點擊鍵盤上的Esc鍵,輸入“:wq”回車,這樣就保存了設置的定時任務,屏幕上也能看到提示創建了新的定時任務。接下來就是好好寫你的script.php了。

關于CronTab的更多用法這里就不介紹了,如果你想更靈活的使用這個定時任務功能,應該自己再去深入學習一下crontab。

二、Windows服務器上使用bat定時執行php

windows上和linux上有一個類似的cmd和bat文件,bat文件類似于shell文件,執行這個bat文件,就相當于依次執行里面的命令(當然,還可以通過邏輯來實現編程),所以,我們可以利用bat命令文件在windows服務器上面實現PHP定時任務。實際上在windows上定時任務,和linux上道理是一樣的,只不過方法和途徑不同。好了下面開始。

首先,在一個你覺得比較適當的位置創建一個cron.bat文件,然后用文本編輯器打開它(記事本都可以),在里面寫上這樣的內容:

D:/php/php.exe -q D:/website/test.php
這句話的意思就是,使用php.exe去執行test.php這個php文件,和上面的contab一樣,繞過了服務器環境,執行效率也比較高。寫好之后,點擊保存,關閉編輯器。

接下來就是設置定時任務來運行cron.bat。依次打開:“開始–>控制面板–>任務計劃–>添加任務計劃”,在打開的界面中設置定時任務的時間、密碼,通過選擇,把cron.bat掛載進去。確定,這樣一個定時任務就建立好了,在這個定時任務上右鍵,運行,這個定時任務就開始執行了,到點時,就會運行cron.bat處理,cron.bat再去執行php。

三、非自有服務器(虛擬主機)上實現php定時任務

如果站長沒有自己的服務器,而是租用虛擬主機,就無法進入服務器系統進行上述操作。這個時候應該如何進行php定時任務呢?其實方法又有多個。

1、使用ignore_user_abort(true)和sleep死循環

在一個php文檔的開頭直接來一句:

ignore_user_abort(true);

這時,通過url訪問這個php的時候,即使用戶把瀏覽器關掉(斷開連接),php也會在服務器上繼續執行。利用這個特性,我們可以實現非常牛的功能,也就是通過它來實現定時任務的激活,激活之后就隨便它自己怎么辦了,實際上就有點類似于后臺任務。

而sleep(n)則是指當程序執行到這里時,暫時不往下執行,而是休息n秒鐘。如果你訪問這個php,就會發現頁面起碼要加載n秒鐘。實際上,這種長時間等待的行為是比較消耗資源的,不能大量使用。

那么定時任務到底怎么實現呢?使用下面的代碼即可實現:

 

<?phpignore_user_abort(true);set_time_limit(0);date_default_timezone_set('PRC'); // 切換到中國的時間$run_time = strtotime('+1 day'); // 定時任務第一次執行的時間是明天的這個時候$interval = 3600*12; // 每12個小時執行一次if(!file_exists(dirname(__FILE__).'/cron-run')) exit(); // 在目錄下存放一個cron-run文件,如果這個文件不存在,說明已經在執行過程中了,該任務就不能再激活,執行第二次,否則這個文件被多次訪問的話,服務器就要崩潰掉了do { if(!file_exists(dirname(__FILE__).'/cron-switch')) break; // 如果不存在cron-switch這個文件,就停止執行,這是一個開關的作用 $gmt_time = microtime(true); // 當前的運行時間,精確到0.0001秒 $loop = isset($loop) && $loop ? $loop : $run_time - $gmt_time; // 這里處理是為了確定還要等多久才開始第一次執行任務,$loop就是要等多久才執行的時間間隔 $loop = $loop > 0 ? $loop : 0; if(!$loop) break; // 如果循環的間隔為零,則停止 sleep($loop);  // ... // 執行某些代碼 // ... @unlink(dirname(__FILE__).'/cron-run'); // 這里就是通過刪除cron-run來告訴程序,這個定時任務已經在執行過程中,不能再執行一個新的同樣的任務 $loop = $interval;} while(true);

通過執行上面這段php代碼,即可實現定時任務,直到你刪除cron-switch文件,這個任務才會停止。

但是有一個問題,也就是如果用戶直接訪問這個php,實際上沒有任何作用,頁面也會停在這個地方,一直處于加載狀態,有沒有一種辦法可以消除這種影響呢?fsockopen幫我們解決了這個問題。

fsockopen可以實現在請求訪問某個文件時,不必獲得返回結果就繼續往下執行程序,這是和curl通常用法不一樣的地方,我們在使用curl訪問網頁時,一定要等curl加載完網頁后,才會執行curl后面的代碼,雖然實際上curl也可以實現“非阻塞式”的請求,但是比fsockopen復雜的多,所以我們優先選擇fsockopen,fsockopen可以在規定的時間內,比如1秒鐘以內,完成對訪問路徑發出請求,完成之后就不管這個路徑是否返回內容了,它的任務就到這里結束,可以繼續往下執行程序了。利用這個特性,我們在正常的程序流中加入fsockopen,對上面我們創建的這個定時任務php的地址發出請求,即可讓定時任務在后臺執行。如果上面這個php的url地址是www.yourdomain.com/script.php,那么我們在編程中,可以這樣:

// ...// 正常的php執行程序// ..// 遠程請求(不獲取內容)函數,下面可以反復使用function _sock($url) { $host = parse_url($url,PHP_URL_HOST); $port = parse_url($url,PHP_URL_PORT); $port = $port ? $port : 80; $scheme = parse_url($url,PHP_URL_SCHEME); $path = parse_url($url,PHP_URL_PATH); $query = parse_url($url,PHP_URL_QUERY); if($query) $path .= '?'.$query; if($scheme == 'https') {  $host = 'ssl://'.$host; } $fp = fsockopen($host,$port,$error_code,$error_msg,1); if(!$fp) {  return array('error_code' => $error_code,'error_msg' => $error_msg); } else {  stream_set_blocking($fp,true);//開啟了手冊上說的非阻塞模式  stream_set_timeout($fp,1);//設置超時  $header = "GET $path HTTP/1.1/r/n";  $header.="Host: $host/r/n";  $header.="Connection: close/r/n/r/n";//長連接關閉  fwrite($fp, $header);  usleep(1000); // 這一句也是關鍵,如果沒有這延時,可能在nginx服務器上就無法執行成功  fclose($fp);  return array('error_code' => 0); }}_sock('www.yourdomain.com/script.php');// ...// 繼續執行其他動作// ..

把這段代碼加入到某個定時任務提交結果程序中,在設置好時間后,提交,然后執行上面這個代碼,就可以激活該定時任務,而且對于提交的這個用戶而言,沒有任何頁面上的堵塞感。

2、借用用戶的訪問行為來執行某些延遲任務

但是上面使用sleep來實現定時任務,是效率很低的一種方案。我們希望不要使用這種方式來執行,這樣的話就可以解決效率問題。我們借用用戶訪問行為來執行任務。用戶對網站的訪問其實是一個非常豐富的行為資源,包括搜索引擎蜘蛛對網站的訪問,都可以算作這個類型。在用戶訪問網站時,內部加一個動作,去檢查任務列表中是否存在沒有被執行的任務,如果存在,就將這個任務執行。對于用戶而言,利用上面所說的fsockopen,根本感覺不到自己的訪問竟然還做出了這樣的貢獻。但是這種訪問的缺點就是訪問很不規律,比如你希望在凌晨2點執行某項任務,但是這個時間段非常倒霉,沒有用戶或任何行為到達你的網站,直到早上6點才有一個新訪問。這就導致你原本打算2點執行的任務,到6點才被執行。

這里涉及到一個定時任務列表,也就是說你需要有一個列表來記錄所有任務的時間、執行什么內容。一般來說,很多系統會采用數據庫來記錄這些任務列表,比如wordpress就是這樣做的。我則利用文件讀寫特性,提供了托管在github上的開源項目php-cron,你可以去看看。總之,如果你想要管理多個定時任務,靠上面的單個php是無法合理布局的,必須想辦法構建一個schedules列表。由于這里面的邏輯比較復雜,就不再詳細闡述,我們僅停留在思路層面上。

3、借用第三方定時任務跳板

很好玩的是,一些服務商提供了各種類型的定時任務,例如阿里云的ACE提供了單獨的定時任務,你可以填寫自己應用下的某個uri。百度云BCE提供了服務器監測功能,每天會按照一定的時間規律訪問應用下的固定uri。類似的第三方平臺上還有很多定時任務可以用。你完全可以用這些第三方定時任務作為跳板,為你的網站定時任務服務。比如說,你可以在阿里云ACE上建立一個每天凌晨2點的定時任務,執行的uri是/cron.php。然后你創建一個cron.php,里面則采用fsockopen去訪問你真正要執行某些任務的網站的url,例如上面的www.yourdomain.com/script.php,而且在cron.php中還可以訪問多個url。然后把cron.php上傳到你的ACE上面去,讓ACE的定時任務去訪問/cron.php,然后讓cron.php去遠程請求目標網站的定時任務腳本。

4、循環利用include包含文件(待驗證)

php面向過程的特性使得其程序是從上往下執行的,利用這個特性,在我們使用include某個文件時,就會執行被引入的文件,知道include的文件內程序執行完之后,再往下執行。如果我們創建一個循環,再利用sleep,不斷的include某個文件,使循環執行某段程序,則可以達到定時執行的目的。我們再進一步,并不是利用while(true)來實現循環,而是利用被include文件本身再include自身來實現循環,比如我們創建一個do.php,它的內容如下:

if(...) exit(); // 通過某個開關來關閉執行// ... // 執行某些程序// ...sleep($loop); // 這個$loop在include('do.php');之前賦值include(dirname(__FILE__).'/do.php');

其實通過這種方法執行和while的思路也像。而且同樣用到sleep,效率低。

PHP定時任務是一個非常有意思的東西,雖然說實話,用系統的php.exe去直接執行php文件的效率更高,但是對于很多普通站長而言,虛擬主機是無法做到直接php執行原生程序的。本文僅提供一些解決的思路,我也僅僅是在學習中,有很多問題或表述都不正確,希望你指出來;你可以通過本文的思路,開發出自己的一種解決方案。

以上就是本文的全部內容,希望對大家的學習有所幫助。



注:相關教程知識閱讀請移步到PHP教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品扒开腿爽爽爽视频| 91热福利电影| 98精品在线视频| 97精品在线观看| 中文字幕欧美在线| 日韩精品免费综合视频在线播放| 亚洲人成电影网站色…| 亚洲自拍在线观看| 九九精品在线观看| 欧美电影免费观看高清| 国产日韩在线精品av| 日韩电影在线观看免费| 欧美日本在线视频中文字字幕| 2018国产精品视频| 亚洲综合大片69999| 精品国产乱码久久久久久虫虫漫画| 成人美女免费网站视频| 国产91露脸中文字幕在线| 夜夜躁日日躁狠狠久久88av| 爽爽爽爽爽爽爽成人免费观看| 亚洲精品久久久久久下一站| 18一19gay欧美视频网站| 91精品视频专区| 欧美一区二粉嫩精品国产一线天| 日韩中文字幕在线精品| 中文字幕免费精品一区高清| 国产一区二区欧美日韩| 欧美猛少妇色xxxxx| 91精品久久久久久久久久| 国产精品无av码在线观看| 国产精品自拍网| 538国产精品视频一区二区| 精品国产老师黑色丝袜高跟鞋| 午夜精品久久久99热福利| 国产精品中文久久久久久久| 亚洲精品免费一区二区三区| 欧美极品美女视频网站在线观看免费| 久久久久久久久久久91| 亚洲香蕉伊综合在人在线视看| 欧美xxxx综合视频| 中文字幕无线精品亚洲乱码一区| 国产精品入口尤物| 亚洲一区二区中文| 欧美一乱一性一交一视频| 国产精品三级久久久久久电影| 亚洲最大中文字幕| 中文在线不卡视频| 国产精品久久久久久久久免费看| 91久久综合亚洲鲁鲁五月天| 欧美激情国产日韩精品一区18| 热99精品只有里视频精品| 欧美精品中文字幕一区| 亚洲自拍偷拍色片视频| 欧美体内谢she精2性欧美| 韩国国内大量揄拍精品视频| 日韩电视剧在线观看免费网站| 日韩成人网免费视频| 久久人人爽人人爽爽久久| 热久久免费视频精品| 高清欧美性猛交xxxx| 午夜精品三级视频福利| 亚洲欧美www| 亚洲欧洲成视频免费观看| 国产欧美日韩精品专区| 亚洲第一区第二区| 欧美日韩免费在线| 久久久久久久久久久久久久久久久久av| 亚洲精品av在线播放| 欧美亚洲另类激情另类| 亚洲一区二区久久久久久久| 国产精品一二三视频| 一级做a爰片久久毛片美女图片| 日韩欧美在线免费观看| 亚洲精品福利资源站| 国产精品久久久一区| 热门国产精品亚洲第一区在线| 欧美寡妇偷汉性猛交| 国产精品一香蕉国产线看观看| 国产精品久久久久久久午夜| 午夜精品久久久久久99热| 91国产视频在线| 国产日韩欧美另类| 欧美一区三区三区高中清蜜桃| 97免费中文视频在线观看| 菠萝蜜影院一区二区免费| 国产有码在线一区二区视频| 国产成人精品在线| 久久久爽爽爽美女图片| 国产精品v日韩精品| 亚洲影院高清在线| 81精品国产乱码久久久久久| 亚洲人成网站在线播| 国产美女精彩久久| 成人黄色午夜影院| 精品视频中文字幕| 最近2019中文字幕一页二页| 精品一区二区亚洲| 亚洲精品wwww| 欧美黑人视频一区| 孩xxxx性bbbb欧美| 在线看日韩av| 中文字幕日韩高清| 岛国av一区二区| 中文字幕精品在线| 欧美性猛交xxxx富婆弯腰| 国产性色av一区二区| 日韩av在线一区二区| 国产精品视频99| 日韩免费电影在线观看| 国产午夜精品视频免费不卡69堂| 午夜免费在线观看精品视频| 狠狠躁天天躁日日躁欧美| 久久综合国产精品台湾中文娱乐网| 精品亚洲国产成av人片传媒| 社区色欧美激情 | 92看片淫黄大片欧美看国产片| 日韩福利在线播放| 92国产精品视频| 2019中文字幕在线观看| 97视频在线看| 日韩av日韩在线观看| 国产成人高潮免费观看精品| 亚洲精品日韩在线| 两个人的视频www国产精品| 国产一区二区三区久久精品| 日韩高清人体午夜| 国产精品视频成人| 国产成人一区二区三区| 日本午夜在线亚洲.国产| 成人黄色免费在线观看| 亚洲视频在线观看免费| 欧美成人免费全部| 欧美性极品xxxx娇小| 国产精品网红直播| 国产盗摄xxxx视频xxx69| 亚洲国产欧美在线成人app| 亚洲色图15p| 亚洲乱码一区二区| 日韩中文综合网| 国产精品永久免费视频| 国产香蕉97碰碰久久人人| 国产美女久久精品| 永久免费毛片在线播放不卡| 国产精品久久久久免费a∨大胸| 国产做受高潮69| 日韩电影免费在线观看中文字幕| 国产精品美女www爽爽爽视频| 久久久久久综合网天天| 成人日韩av在线| 日韩av在线网址| 中文日韩在线视频| 亚洲精品美女网站| 久久综合电影一区| 国产精品精品视频| 亚洲free性xxxx护士白浆| 91麻豆国产语对白在线观看| 另类图片亚洲另类| 亚洲人成电影网站色www| 色综合男人天堂| 91免费看片在线| 色无极亚洲影院| 亚洲午夜未满十八勿入免费观看全集| 97视频在线观看免费| 欧美久久精品午夜青青大伊人|