我有一個PHP的cronjob系統。我有一個名爲cron.php的文件,並想檢查它是否沒有加載,請加載它。這個文件只運行一次對我來說非常重要,我需要如何定義它已經運行的方式。我不能使用任何系統功能,如exec,system,...你有任何解決方案嗎?如何確保一次PHP腳本加載
注意:我運行我的腳本通過CURL和include_one和require_once不適用於這種情況。
我有一個PHP的cronjob系統。我有一個名爲cron.php的文件,並想檢查它是否沒有加載,請加載它。這個文件只運行一次對我來說非常重要,我需要如何定義它已經運行的方式。我不能使用任何系統功能,如exec,system,...你有任何解決方案嗎?如何確保一次PHP腳本加載
注意:我運行我的腳本通過CURL和include_one和require_once不適用於這種情況。
你可以使用flock()
鎖定php文件本身,像這樣:
<?php
class Lock{
private $fp;
function __construct(){
$this->fp=fopen(__FILE__,'r');
if (!flock($this->fp,LOCK_EX|LOCK_NB)) {
die('already running !'.PHP_EOL);
}
}
function __destruct(){
flock($this->fp,LOCK_UN);
fclose($this->fp);
}
}
$lock=new Lock();
// simulate some processing
sleep(60);
echo "END";
?>
您可以只使用require_once或include_once?
require_once
將拋出一個PHP致命錯誤(將停止執行),如果該文件無法評估。 include_once
會拋出PHP警告(執行可能會繼續)。
// Require tasks.php to run once
require_once 'path/to/tasks.php';
// Attempt to run tasks.php and only once
include_once 'path/to/tasks.php';
可以使用require_once
或include_once
既包括和要求語句的一般語法如下:
include "file_to_load.php";
include_once "file_to_load.php";
當使用include_once/require_once
報表,文件無法加載或執行多次。如果嘗試使用這兩種方法之一加載文件兩次,它將被忽略。因爲在腳本中多次定義相同的函數是不可接受的,所以這些函數允許開發人員根據需要包含腳本,而不必檢查它是否先前已加載過。
備註從外部文件返回值的功能僅限於include_once
語句。 require_once
聲明不能以這種方式使用。
這是不正確的。我通過CURL運行我的腳本。 include_one是爲每個客戶端,我希望我的腳本運行一次爲所有客戶 – IVIR3zaM
include_once('class.php');
php.net指出
的include_once語句包括和腳本的執行過程中運行指定文件 。這是一種類似於 include語句的行爲,唯一的區別是如果文件中的代碼 已包含在內,則不會再包含它。顧名思義,它只會包含一次。
您可以使用require_once或include_once。
,如果你是混淆使用什麼那麼這兩者之間的區別是,
require_once將停止執行上面的代碼中,trwos致命的錯誤,如果上述文件未找到 所以如果你想前面的代碼繼續即使文件沒有找到,那就不要使用它。
其中include_once將繼續執行前面的代碼。
它是好的,但不能正常工作,在我的腳本許多作品執行,可能需要很長時間,從秒傳遞,在這種情況下,我的腳本認爲它沒有運行並再次運行 – IVIR3zaM
如果我理解正確的話,你要阻止cron.php腳本從第二次由cron開始,它不會從另一個PHP腳本調用? (在這種情況下,require_once將是正確的答案)
據我所知,你需要存儲一個標誌,指示你的腳本運行,並刪除該標記在腳本的結尾。
取決於你的環境,你既可以創建一個小文件,即.lock
或在數據庫中存儲狀態=鎖定條目。
編輯:下面是一個使用文件的方法一個小的代碼示例:
<?php
// cron.php
$path = '/path/to/your/data/directory/';
if (file_exists($path . '.lock') {
die('cron.php is already running');
}
// if script reaches this point, it is not locked -> create a lock
file_put_contents($path . '.lock', 'lockfile created at ' . now());
//... your code....
//unlocking
unlink($path . '.lock');
?>
您可以使用數據庫進行這種情況下,在數據庫中輸入頁面,在第二欄輸入數據,檢查是否加載(例如,'0'
如果尚未加載,則加載'1'
)。加載頁面時,最初將該行的值保存爲'0'
,將該列更新爲'1'
。
如果使用捲曲那麼我相信你正在使用cURL來請求一個頁面,如http://domain.com/cron.php
。通過cURL/wget/browser/etc請求腳本的機器無法知道腳本是否已經在服務器上執行。但是,你可以配置你cron.php
腳本只運行一次:
<?php
// attempt to obtain a lock
$fp = fopen(basename(__FILE__) . ".lock", "w");
if (flock($fp, LOCK_EX | LOCK_NB) === false) {
echo basename(__FILE__) . ": already running\n";
exit(-1);
}
// code goes here
echo date("Y-m-d H:i:s") . ": cron job started\n";
sleep(30);
echo date("Y-m-d H:i:s") . ": cron job ended\n";
// release the lock
flock($fp, LOCK_UN);
fclose($fp);
的代碼示例使用PHP flock
功能。 LOCK_EX
標誌告訴PHP它需要獲得排他鎖;即不允許其他進程訪問該文件。 LOCK_NB
告訴PHP它不應該阻塞(等待鎖被釋放)並立即返回false
。兩個開關一起確保第二個進程在第一個進程鎖定時不能鎖定文件。
您的意思是說,如果現有的程序已經在執行,您是否希望避免運行cron作業cron.php? (因爲這與目前得到的答案有很大的不同,所以你應該澄清一下..) – Ben
先生看到我的答案,並讓我知道我是否落後於某處 –
您將不得不將腳本的最後執行時間存儲在某處數據庫,文本文件)。然後檢查最後一次執行時間/日期(用戶ID等),只有在給定條件(超時)時才執行腳本。 – djot