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 相关文章推荐
检查url链接是否已经有参数的php代码 添加 ? 或 &amp;
Feb 09 PHP
php递归创建和删除文件夹的代码小结
Apr 13 PHP
深入理解ob_flush和flush的区别(ob_flush()与flush()使用方法)
Feb 06 PHP
php用户注册时常用的检验函数实例总结
Dec 22 PHP
PHP自带ZIP压缩、解压缩类ZipArchiv使用指南
Mar 03 PHP
PHP 双链表(SplDoublyLinkedList)简介和使用实例
May 12 PHP
深入解析PHP中foreach语句控制数组循环的用法
Nov 30 PHP
PHP模板引擎Smarty内建函数foreach,foreachelse用法分析
Apr 11 PHP
CI框架数据库查询之join用法分析
May 18 PHP
php中照片旋转 (orientation) 问题的正确处理
Feb 16 PHP
php中的钩子理解及应用实例分析
Aug 30 PHP
Yii 实现数据加密和解密
Mar 09 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
php5.3 不支持 session_register() 此函数已启用的解决方法
2013/11/12 PHP
yii实现CheckBox复选框在同一行显示的方法
2014/12/03 PHP
php对文件进行hash运算的方法
2015/04/03 PHP
orm获取关联表里的属性值
2016/04/17 PHP
PHP策略模式定义与用法示例
2017/07/27 PHP
ThinkPhP+Apache+PHPstorm整合框架流程图解
2020/11/23 PHP
JavaScript 解析读取XML文档 实例代码
2009/07/07 Javascript
jQuery 翻牌或百叶窗效果(内容三秒自动切换)
2012/06/14 Javascript
表单元素与非表单元素刷新区别详细解析
2013/11/06 Javascript
为开发者准备的10款最好的jQuery日历插件
2014/02/04 Javascript
判断window.onload是否多次使用的方法
2014/09/21 Javascript
Bootstrap零基础学习第一课之模板
2016/07/18 Javascript
第一次接触Bootstrap框架
2016/10/24 Javascript
基于jQuery实现滚动切换效果
2016/12/02 Javascript
微信小程序 input输入框控件详解及实例(多种示例)
2016/12/14 Javascript
jQuery插件HighCharts实现的2D对数饼图效果示例【附demo源码下载】
2017/03/09 Javascript
Extjs表单输入框异步校验的插件实现方法
2017/03/20 Javascript
jQuery实现鼠标经过显示动画边框特效
2017/03/24 jQuery
three.js中文文档学习之如何本地运行详解
2017/11/20 Javascript
让你5分钟掌握9个JavaScript小技巧
2018/06/09 Javascript
小程序多图列表实现性能优化的方法步骤
2019/05/28 Javascript
微信小程序 数据缓存实现方法详解
2019/08/26 Javascript
Vue如何将页面导出成PDF文件
2020/08/17 Javascript
[55:11]完美世界DOTA2联赛PWL S2 SZ vs LBZS 第一场 11.26
2020/11/30 DOTA
Python中getpass模块无回显输入源码解析
2018/01/11 Python
详解Python之unittest单元测试代码
2018/01/24 Python
用python实现百度翻译的示例代码
2018/03/09 Python
Django用户认证系统 User对象解析
2019/08/02 Python
Python如何进行时间处理
2020/08/06 Python
控制工程专业个人求职信
2013/09/25 职场文书
应聘美工求职信
2013/11/07 职场文书
技术学校毕业生求职信分享
2013/12/02 职场文书
2014教师党员自我评议总结
2014/09/19 职场文书
幼儿园大班个人总结
2015/02/28 职场文书
Java中使用Filter过滤器的方法
2021/06/28 Java/Android
MySQL磁盘碎片整理实例演示
2022/04/03 MySQL