调度php脚本

时间:2011-04-03 00:01:18

标签: php cron scheduling

我想创建一些函数来安排php脚本,例如,如果我想在12/12/2012 12:12 tu run page.php我可以调用

schedule_script('12/12/2012 12:12','page.php');//or by passing a time/datetime object

或者例如每分钟调用一个脚本

schedule_interval(60,'page.php');//every 60s=1minute

我可能会添加一些其他功能来查看已安排的脚本或删除其中一个脚本。

我希望这些功能可以在UNIX和WINDOWS平台上运行,我不想要丑陋的解决方案,比如在网站的每个页面上执行脚本(我希望在没有人在网站上时安排此命令)或使用“buisy”等待“实现(在检查是否存在任何预定作业的脚本上使用sleep())或需要用户干预的内容(例如在控制台中编写内容或打开面板)。

我在MSDOS上找到了“AT”命令(适用于所有窗口),但它非常基本,因为它只接受时间而不是日期,在UNIX上有一个更强大的版本,但我不知道如何使用它(我想为两个平台提供解决方案。)

3 个答案:

答案 0 :(得分:2)

有一个PHP函数可以让你将脚本执行延迟到某个时间点。

所以我要说cron.php

<?php

   // Usage:
   //    cron.php [interval|schedule] [script] [interval|stamp]
   if(!isset($argc) || count($argc)!=2)die; // security precaution

   $time=(int)$argv[3]; // just in case :)

   if($argv[1]=='schedule'){
       time_sleep_until((int)$_GET['until']);
       include_once($time);
   }elseif($argv[1]=='interval')
       while(true){ // this is actually an infinite loop (you didn't ask for an "until" date? can be arranged tho)
           usleep($time*1000); // earlier I said milliseconds: 1000msec is 1s, but this func is for microseconds: 1s = 1000000us
           include_once($argv[2]);
       }

?>

您的classes / functions文件:

// Const form K2F - Are we on windows?
define('ISWIN', strpos(strtolower(php_uname()),'win')!==false &&
                strpos(strtolower(php_uname()),'darwin')===false );

// Function from K2F - runs a shell command without waiting (works on all OSes)
function run($cmd){
    ISWIN ? pclose(popen('start /B '.$cmd,'r')) : exec($cmd.' > /dev/null &');
}

script_schedule($script,$time){
    if(is_string($time))$time=strtotime($time);
    run('php -f -- schedule '.escapeshellarg($script).' '.$time);
}

script_interval($script,$mseconds){
    run('php -f -- interval '.escapeshellarg($script).' '.$mseconds);
}

它应该工作。顺便说一下,K2F就是这个让你的梦想成真的框架。 )。欢呼声。

编辑:如果您仍然需要有关计算正在运行的作业和/或删除(停止)它们的部分,我也可以帮助您解决问题。只需回复我的帖子,我们就会跟进。

答案 1 :(得分:0)

$amt_time = "1";
$incr_time = "day";
$date = "";
$now=  ''. date('Y-m-d') ."";   
if (($amt_time!=='0') && ($incr_time!=='0')) {
$date = strtotime(date("Y-m-d".strtotime($date))."+$amt_time $incr_time");
$startdate=''.date('Y-m-d',$date) ."";
} else {
$startdate="0000-00-00";
}
if ($now == $startdate) {
include ('file.php');
}

只是一个猜测;)实际上我可能会反过来,但你明白了

答案 2 :(得分:0)

这是我的调度程序的实现,我只需要启动它,如果不活动并在mysql作业表上添加所有作业(我已经有一个用于我的主脚本),此脚本将启动所有准备好的作业执行(sql表有一个datetime字段)。

我称之为“Mutex”是一个类,它告诉脚本的一个或多个副本是否正在运行,甚至可以通过管道向运行的脚本发送命令(您只需创建一个具有相同的新互斥锁)所有脚本的名称),因此您甚至可以从另一个脚本停止正在运行的脚本。

<?php
//---logging---
$logfile = dirname(dirname(__FILE__)).'/scheduler.log';
$ob_file = fopen($logfile,'a');
function ob_file_callback($buffer)
{
  global $ob_file;
  fwrite($ob_file,$buffer);
}




//--includes---

  $inc=dirname(dirname(__FILE__)).'/.include/';
  require_once($inc.'Mutex.php');
  require_once($inc.'jobdb.php');
//--mutex---
//i call it mutex but it's nothing like POSIX mutex,it's a way to synchronyze scripts
  $m=new Mutex('jscheduler');
  if(!$m->lock())//if this script is already running
    exit();//only one scheduler at time
//---check loop---
  set_time_limit(-1);//remove script time limit
  for(;;){
      ob_start('ob_file_callback');//logging 

     $j=jobdb_get_ready_jobs(true);//gets all ready jobs,works with mysql
     if($j!=null)//found some jobs
         foreach($j as $val){//run all jobs

            $ex='*SCRIPT NAME AND PARAMETERS HERE*';

            if(!run_script($ex))
                echo "UNABLE TO LAUNCH THE JOB!\n";
        }
     $n=($j!=null)?count($j).'JOBS LAUNCHED':'NO JOBS';


     sleep(60);
     if($m->has_to_stop())//yeah,i can stop this script from other scripts,it works with a file pipeline
        exit("# STOPPING SCHEDULER\n");            

     ob_end_flush();//LOGGING  
  }

?>

我的“run_script”函数与Sciberras“run”函数的工作方式相同。

要激活调度程序,您只需使用此命令

即可
 run_script('scheduler.php');

检查它是否有效

$m=new Mutex('jscheduler');
if(!$m->test_lock())
    echo 'SCHEDULER IS ACTIVE';
else 
    echo 'SCHEDULER IS INACTIVE';

并停止调度程序

$m=new Mutex('jscheduler'); 
$m->ask_to_stop();//simply sent throught the pipe the command,now has_to_stop()will return true on the process that have gain the lock of the mutex
echo 'STOPPING SCHEDULER...';

我可能在他的实现方面走得太远,无论如何可能存在“滞后”问题,例如,如果调度程序从0:00.00开始并且我有两个脚本在0:01.01和0:01.59两者都是发布于0:02.0。 为了解决这个“滞后”,我可能会检索下一分钟安排的所有作业,并使用time_sleep_until在Sciberras代码中安排它们。 这不会创建太多正在运行的线程(我可能想要测试启动HUDGE线程数量是否存在限制或性能下降但我确定会出现一些问题)并确保完美的时序只需检查是否存在调度程序处于活动状态。