編碼的世界 / 優質文選 / 文明

詳解PHP設置定時任務的實現方法 萬次閱讀


2021年7月04日
-   

定時運行任務對於一個網站來說,是一個比較重要的任務,比如定時發布文檔,定時清理垃圾信息等,現在的網站大多數都是采用PHP動態語言開發的,而對於PHP的實現決定了它沒有Java和.Net這種AppServer的概念,而http協議是一個無狀態的協議,PHP只能被用戶觸發,被調用,調用後會自動退出內存,沒有常駐內存。
如果非要PHP去設置定時任務, 可以有以下三個方法:

1、用戶觸發定時


通過掛載到網頁裏面,判斷當前的時間,然後運行PHP代碼,缺點是每一次加載網頁,都需要加載這個PHP頁面,而對於人氣不旺的網站,這樣的延時可能會更加的嚴重,畢竟是用戶的HTTP請求去觸發這個PHP代碼的運行,Discuz!論壇程序是判斷在00:00之後,第一個用戶訪問請求去執行定時的PHP代碼。

2、常駐內存運行


PHP是可以常駐內存運行程序的,下面的這段代碼,可以在當前文件夾下,生成一個test.txt,並每隔20秒,往裏面寫入一個時間戳,無論客戶端是否關閉瀏覽器。
<?php
ignore_user_abort(true);
set_time_limit(0);
function write_txt(){
    if(!file_exists("test.txt")){
        $fp = fopen("test.txt","wb");
        fclose($fp);
    }
    $str = file_get_contents(’test.txt’);
    $str .= "
".date("H:i:s");
    $fp = fopen("test.txt","wb");
    fwrite($fp,$str);
    fclose($fp);
}
function do_cron(){
usleep(20000000);
    write_txt();
}
while(1){
    do_cron();
}
?>

關鍵的兩個函數
ignore_user_abort(true),這個函數的作用是,無論客戶端是否關閉瀏覽器,下面的代碼都將得到執行。
set_time_limit(0),這個函數的作用是,取消PHP文件的執行時間,如果沒有這個函數的話,默認PHP的執行時間是30秒,也就是說30秒後,這個文件就會從內存中刪除。
另外usleep函數是在PHP5.0後的版本中加入的函數,支持Windows操作系統,設置代碼運行的時間,單位是毫秒(MS)。
如何停止定時
但是當我執行腳本的時候,即使我關閉了瀏覽器,我根本就沒法去停止這段程序了,所以你需要一個執行腳本的開關,你可以用外部文件引入的方法來實現,在while循環的時候,include開關變量即可。那麼就可以這樣實現:
建立外部引入變量文件 switch.php 內容如下:
<?php
return 1;//1執行腳本 0退出執行腳本
?>

這個腳本只是測試可行,具體效率應該不高,對於lamp,你完全可以使用crontab 來實現。

3、服務器定時任務


服務器定時任務需要你是獨立的服務器,或者是VPS,總之就是對系統的配置有足夠的權限,虛擬空間就不要折騰這個方法了,因為你沒有權限。
Windows平台
在 Windows 平台下您可以將cliphp.exe 和 .php 文件的雙擊屬性相關聯,您也可以編寫一個批處理文件來用 PHP 執行腳本。我們把寫好的程序放在一個目錄下如 E:webmail.php
然後寫一個windows批處理文件內容如下:
@D:phpcliphp.exe E:webmail.php >d:phpclisendmail.log
Pause

那個 D:phpcliphp.exe 是我的PHP安裝文件所在目錄。Php.exe 就是windows PHP命令行模式的程序。
好的,我們保存這個文件為 mail.bat 然後的windows中的計劃任務中添加一個任務,讓操作系統在某個時間來運行這個批處理文件。
Unix平台
如果您使用 Unix 系統,您需要在您的 PHP 腳本的最前面加上一行特殊的代碼,使得它能夠被執行,這樣系統就能知道用什麼樣的程序要運行該腳本。為 Unix 系統增加的第一行代碼不會影響該腳本在 Windows 下的運行,因此您也可以用該方法編寫跨平台的腳本程序。
在Crontab中使用PHP執行腳本就像在Crontab中調用普通的shell腳本一樣(具體Crontab用法),使用PHP程序來調用PHP腳本,每一小時執行 myscript.php 如下:
# crontab -e
00 * * * * /usr/local/bin/php /home/john/myscript.php

/usr/local/bin/php為PHP程序的路徑。
在Crontab中使用URL執行腳本如果你的PHP腳本可以通過URL觸發,你可以使用 lynxcurlwget 來配置你的Crontab。
下面的例子是使用Lynx文本瀏覽器訪問URL來每小時執行PHP腳本。Lynx文本瀏覽器默認使用對話方式打開URL。但是,像下面的,我們在lynx命令行中使用-dump選項來把URL的輸出轉換來標准輸出。
00 * * * * lynx -dump http://www.uedsc.net/myscript.php

下面的例子是使用 CURL 訪問URL來每5分執行PHP腳本。Curl默認在標准輸出顯示輸出。使用 "curl -o" 選項,你也可以把腳本的輸出轉儲到臨時文件。
*/5 * * * * /usr/bin/curl -o temp.txt http://www.uedsc.net/myscript.php

下面的例子是使用WGET訪問URL來每10分執行PHP腳本。-q 選項表示安靜模式。"-O temp.txt" 表示輸出會發送到臨時文件。
*/10 * * * * /usr/bin/wget -q -O temp.txt http://www.uedsc.net/myscript.php

熱門文章