PHP中实现crontab代码分享


Posted in PHP onMarch 26, 2015

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 ) continue;
 $cmd       = array_pop($slices);

 $cron_time = implode(' ', $slices);

 $next_time = Crontab::parse($cron_time, $now);

 if ( $next_time !== $now ) continue; 
 $pid = pcntl_fork();

 if ($pid == -1) {

  die('could not fork');

 } else if ($pid) {

  // we are the parent

  pcntl_wait($status, WNOHANG); //Protect against Zombie children

 } else {

      // we are the child

  `$cmd`;

  exit;

 }

}
/* https://github.com/jkonieczny/PHP-Crontab */

class Crontab {

   /**

 * Finds next execution time(stamp) parsin crontab syntax,

 * after given starting timestamp (or current time if ommited)

 *

 * @param string $_cron_string:

 *

 * 0 1 2 3 4

 * * * * * *

 * - - - - -

 * | | | | |

 * | | | | +----- day of week (0 - 6) (Sunday=0)

 * | | | +------- month (1 - 12)

 * | | +--------- day of month (1 - 31)

 * | +----------- hour (0 - 23)

 * +------------- min (0 - 59)

 * @param int $_after_timestamp timestamp [default=current timestamp]

 * @return int unix timestamp - next execution time will be greater

 * than given timestamp (defaults to the current timestamp)

 * @throws InvalidArgumentException

 */

    public static function 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("Invalid cron string: ".$_cron_string);

        }

        if($_after_timestamp && !is_numeric($_after_timestamp)){

            throw new InvalidArgumentException("\$_after_timestamp must be a valid unix timestamp ($_after_timestamp given)");

        }

        $cron = preg_split("/[\s]+/i",trim($_cron_string));

        $start = empty($_after_timestamp)?time():$_after_timestamp;
        $date = array( 'minutes' =>self::_parseCronNumbers($cron[0],0,59),

                            'hours' =>self::_parseCronNumbers($cron[1],0,23),

                            'dom' =>self::_parseCronNumbers($cron[2],1,31),

                            'month' =>self::_parseCronNumbers($cron[3],1,12),

                            'dow' =>self::_parseCronNumbers($cron[4],0,6),

                        );

        // limited to time()+366 - no need to check more than 1year ahead

        for($i=0;$i<=60*60*24*366;$i+=60){

            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['minutes'])
                ){

                    return $start+$i;

            }

        }

        return null;

    }
    /**

 * get a single cron style notation and parse it into numeric value

 *

 * @param string $s cron string element

 * @param int $min minimum possible value

 * @param int $max maximum possible value

 * @return int parsed number

 */

    protected static function _parseCronNumbers($s,$min,$max)

    {

        $result = array();
        $v = explode(',',$s);

        foreach($v as $vv){

            $vvv = explode('/',$vv);

            $step = empty($vvv[1])?1:$vvv[1];

            $vvvv = explode('-',$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<=$_max;$i+=$step){

                $result[$i]=intval($i);

            }

        }

        ksort($result);

        return $result;

    }

}
PHP 相关文章推荐
PHP调用三种数据库的方法(1)
Oct 09 PHP
PHP生成静态页面详解
Dec 05 PHP
Zend Studio 无法启动的问题解决方法
Dec 04 PHP
PHP 面向对象 PHP5 中的常量
May 05 PHP
ubuntu下编译安装xcache for php5.3 的具体操作步骤
Jun 18 PHP
ThinkPHP采用实现三级循环代码实例
Jul 18 PHP
php实现比较两个文件夹异同的方法
Jun 18 PHP
文件上传之SWFUpload插件(代码)
Jul 30 PHP
基于PHP技术开发客服工单系统
Jan 06 PHP
如何批量清理系统临时文件(语言:C#、 C/C++、 php 、python 、java )
Feb 01 PHP
PHP+redis实现的限制抢购防止商品超发功能详解
Sep 19 PHP
PHP实现长轮询消息实时推送功能代码实例讲解
Feb 26 PHP
PHP利用hash冲突漏洞进行DDoS攻击的方法分析
Mar 26 #PHP
ThinkPHP、ZF2、Yaf、Laravel框架路由大比拼
Mar 25 #PHP
CentOS 安装 PHP5.5+Redis+XDebug+Nginx+MySQL全纪录
Mar 25 #PHP
MacOS 安装 PHP的图片裁剪扩展Tclip
Mar 25 #PHP
php编写的一个E-mail验证类
Mar 25 #PHP
php取得字符串首字母的方法
Mar 25 #PHP
PHP判断IP并转跳到相应城市分站的方法
Mar 25 #PHP
You might like
弄了个检测传输的参数是否为数字的Function
2006/12/06 PHP
处理php自动反斜杠的函数代码
2010/01/05 PHP
php中比较简单的导入phpmyadmin生成的sql文件的方法
2011/06/28 PHP
php 验证码(倾斜,正弦干扰线,黏贴,旋转)
2013/06/29 PHP
PHP 进程池与轮询调度算法实现多任务的示例代码
2019/11/26 PHP
语义化 H1 标签
2008/01/14 Javascript
jquery 弹出层注册页面等(asp.net后台)
2010/06/17 Javascript
在javascript将NodeList作为Array数组处理的方法
2010/07/09 Javascript
解析javascript 数组以及json元素的添加删除
2013/06/26 Javascript
javascript中typeof的使用示例
2013/12/19 Javascript
使用jQuery设置disabled属性与移除disabled属性
2014/08/21 Javascript
Nodejs学习笔记之Stream模块
2015/01/13 NodeJs
Jquery和Js获得元素标签名称的方法总结
2016/10/08 Javascript
javascript实现延时显示提示框效果
2017/06/01 Javascript
JS实现全屏预览F11功能的示例代码
2018/07/23 Javascript
VUE脚手架的下载和配置步骤详解
2019/04/01 Javascript
JS实现的雪花飘落特效示例
2019/12/03 Javascript
python获取豆瓣电影简介代码分享
2014/01/16 Python
Python字符串中查找子串小技巧
2015/04/10 Python
在Python中处理列表之reverse()方法的使用教程
2015/05/21 Python
pytorch对可变长度序列的处理方法详解
2018/12/08 Python
Numpy之将矩阵拉成向量的实例
2019/11/30 Python
树莓派升级python的具体步骤
2020/07/05 Python
python 对象真假值的实例(哪些视为False)
2020/12/11 Python
OPPO手机官方商城:中国手机市场出货量第一品牌
2017/10/18 全球购物
波兰珠宝品牌:YES
2019/08/09 全球购物
LN-CC日本:高端男装和女装的奢侈时尚目的地
2019/09/01 全球购物
临时用工协议书范本
2014/10/29 职场文书
教师党的群众路线教育实践活动学习笔记
2014/11/05 职场文书
2014年个人教学工作总结
2014/12/09 职场文书
庐山导游词
2015/02/03 职场文书
储备店长岗位职责
2015/04/14 职场文书
运动会5000米加油稿
2015/07/21 职场文书
预备党员入党感言
2015/08/01 职场文书
MySQL Innodb索引机制详细介绍
2021/11/23 MySQL
《进击的巨人》新联动CM 兵长强势出击兽巨人
2022/04/05 日漫