我有一个带PHP的cronjob系统。我有一个名为cron.php的文件,想要检查它是否未加载,加载它。对我来说这个文件只运行一次非常重要,我需要定义它已经运行的方式。我不能使用任何系统功能,如exec,system,......你有任何解决方案吗?
注意:我通过CURL运行我的脚本,include_one和require_once不适合这种情况。
答案 0 :(得分:7)
您可以使用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";
?>
答案 1 :(得分:2)
您可以使用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';
答案 2 :(得分:2)
答案 3 :(得分:2)
如果我理解正确,你想阻止你的cron.php脚本第二次被cron启动,它是不是从另一个PHP脚本调用的? (在这种情况下,require_once将是正确答案)
据我了解,您需要存储一个标记,指示您的脚本正在运行,并在脚本末尾删除该标记。
根据您的环境,您可以创建一个小文件,即.lock
或在数据库中存储status = locked条目。
编辑:这是一个使用文件方法的小代码示例:
<?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');
?>
答案 4 :(得分:2)
如果您使用的是cURL,我相信您正在使用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
。这两个开关一起确保第二个进程无法锁定文件,而第一个进程已将其锁定。
答案 5 :(得分:1)
您可以使用require_once
或include_once
include和require语句的一般语法如下:
include "file_to_load.php";
include_once "file_to_load.php";
使用include_once/require_once
语句时,无法多次加载或执行文件。如果尝试使用这两种方法之一加载文件两次,则会被忽略。由于在脚本中多次定义相同的函数是不可接受的,因此这些函数允许开发人员根据需要包含脚本,而无需检查它是否先前已加载过。
注意从外部文件返回值的功能仅限于include_once
语句。 require_once
语句不能以这种方式使用。
答案 6 :(得分:1)
include_once('class.php');
php.net陈述
include_once语句包含并评估指定的文件 在执行脚本期间。这是一种类似的行为 include语句,唯一不同的是如果代码 从文件已经包含,它将不会再包括在内。 顾名思义,它只包含一次。
答案 7 :(得分:0)
您可以使用require_once或include_once。
如果你混淆使用什么,那么这两者之间的区别就在于
如果找不到提到的文件,require_once将停止执行前面的代码,trwos致命错误 因此,如果您希望前面的代码继续,即使找不到文件,也不要使用它。
其中include_once将继续执行前面的代码。
答案 8 :(得分:0)
您可以在这种情况下使用数据库,在数据库和第二列中输入页面以检查是否已加载(例如'0'
如果尚未加载,'1'
它是加载)。加载页面时,最初将该行的值保留为'0'
,将该列更新为'1'
。