首页  >  文章  >  后端开发  >  PHP中实现crontab代码分享_php实例

PHP中实现crontab代码分享_php实例

WBOY
WBOY原创
2016-06-07 17:13:41740浏览

1. 准备一个标准crontab文件 ./crontab

复制代码 代码如下:

# m h dom mon dow command
* * * * * date > /tmp/cron.date.run

2. crontab -e 将此cron.php脚本加入系统cron

复制代码 代码如下:

* * * * * /usr/bin/php cron.php

3. cron.php 源码

复制代码 代码如下:

// 从./crontab读取cron项,也可以从其他持久存储(mysql、redis)读取
$crontab = file('./crontab');
$now = $_SERVER['REQUEST_TIME'];

foreach ( $crontab as $cron ) {
 $slices = preg_split("/[s] /", $cron, 6);
 if( count($slices) !== 6 ) 继续;

 $cmd       = array_pop($slices);
 $cron_time = implode(' ', $slices);
 $next_time = Crontab::parse($cron_time, $now);
 if ( $next_time !== $now ) 继续; 

 $pid = pcntl_fork();
 if ($pid == -1) {
  die('无法分叉');
 } else if ($pid) {
  // 我们是父级
  pcntl_wait($status, WNOHANG); //防止僵尸儿童
 } 其他 {
      // 我们是孩子
  `$cmd`;
  退出;
 }
}

/* https://github.com/jkonieczny/PHP-Crontab */
类 Crontab {
   /**
 * 查找下一个执行时间(标记)解析 crontab 语法,
 * 在给定开始时间戳(或当前时间,如果省略)之后
 *
 * @param string $_cron_string:
 *
 * 0 1 2 3 4
 * * * * * *
 * - - - - -
 * | | | | |
 * | | | | ----- 星期几 (0 - 6)(星期日=0)
 * | | | ------- 月 (1 - 12)
 * | | --------- 一个月中的某一天 (1 - 31)
 * | ----------- 小时 (0 - 23)
 * ------------- 分钟 (0 - 59)
 * @param int $_after_timestamp 时间戳 [默认=当前时间戳]
 * @return int unix timestamp - 下一次执行时间会更长
 * 比给定的时间戳(默认为当前时间戳)
 * @抛出InvalidArgumentException
 */
    公共静态函数parse($_cron_string,$_after_timestamp=null)
    {
        if(!preg_match('/^((*(/[0-9] )?)|[0-9-,/] )s ((*(/[0-9] )?)|[0-9 -,/] )s ((*(/[0-9] )?)|[0-9-,/] )s ((*(/[0-9] )?)|[0-9-, /] )s ((*(/[0-9] )?)|[0-9-,/] )$/i',trim($_cron_string))){
            throw new InvalidArgumentException("无效的 cron 字符串:".$_cron_string);
        }
        if($_after_timestamp && !is_numeric($_after_timestamp)){
            throw new InvalidArgumentException("$_after_timestamp 必须是有效的 unix 时间戳(给定 $_after_timestamp)");
        }
        $cron = preg_split("/[s] /i",trim($_cron_string));
        $start = 空($_after_timestamp)?time():$_after_timestamp;

        $date = array( '分钟' =>self::_parseCronNumbers($cron[0],0,59),
                            '小时' => self::_parseCronNumbers($cron[1],0,23),
                            'dom' =>self::_parseCronNumbers($cron[2],1,31),
                            '月' => self::_parseCronNumbers($cron[3],1,12),
                            'dow' =>self::_parseCronNumbers($cron[4],0,6),
                        );
        // 仅限于 time() 366 - 无需提前检查超过 1 年
        for($i=0;$i             if( in_array(intval(date('j',$start $i)),$date['dom']) &&
                in_array(intval(date('n',$start $i)),$date['month']) &&
                in_array(intval(date('w',$start $i)),$date['dow']) &&
                in_array(intval(date('G',$start $i)),$date['hours']) &&
                in_array(intval(date('i',$start $i)),$date['分钟'])

                ){
                    返回 $start $i;
            }
        }
        返回空;
    }

    /**
 * 获取单个 cron 样式符号并将其解析为数值
 *
 * @param string $s cron 字符串元素
 * @param int $min 最小可能值
 * @param int $max 最大可能值
 * @return int 解析后的数字
 */
    受保护的静态函数 _parseCronNumbers($s,$min,$max)
    {
        $结果 = array();

        $v = 爆炸(',',$s);
        foreach($v as $vv){
            $vvv = 爆炸('/',$vv);
            $step = 空($vvv[1])?1:$vvv[1];
            $vvvv = 爆炸('-',$vvv[0]);
            $_min = count($vvvv)==2?$vvvv[0]:($vvv[0]=='*'?$min:$vvv[0]);
            $_max = count($vvvv)==2?$vvvv[1]:($vvv[0]=='*'?$max:$vvv[0]);

            for($i=$_min;$i                 $结果[$i]=intval($i);
            }
        }
        ksort($结果);
        返回$结果;
    }
}

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn