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中使用Oracle数据库(3)
Oct 09 PHP
UTF8编码内的繁简转换的PHP类
Jul 09 PHP
Discuz 6.0+ 批量注册用户名
Sep 13 PHP
php 读取shell管道传输过来的内容
Mar 01 PHP
用sql命令修改数据表中的一个字段为非空(not null)的语句
Jun 04 PHP
PHP通过header实现文本文件下载的代码
Aug 08 PHP
PHP判断远程url是否有效的几种方法小结
Oct 08 PHP
php获取根域名方法汇总
Oct 28 PHP
PHP中ini_set与ini_get用法实例
Nov 04 PHP
Thinkphp模板标签if和eq的区别和比较实例分析
Jul 01 PHP
PHP框架实现WebSocket在线聊天通讯系统
Nov 21 PHP
Laravel 集成微信用户登录和绑定的实现
Dec 27 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
随时给自己贴的图片加文字的php代码
2007/03/08 PHP
IIS6.0 开启Gzip方法及PHP Gzip函数分享
2014/06/08 PHP
PHP判断文件是否被引入的方法get_included_files用法示例
2016/11/29 PHP
针对thinkPHP5框架存储过程bug重写的存储过程扩展类完整实例
2018/06/16 PHP
浅谈php常用的7大框架的优缺点
2020/07/20 PHP
javascript 对象的定义方法
2007/01/10 Javascript
加载远程图片时,经常因为缓存而得不到更新的解决方法(分享)
2013/06/26 Javascript
struts2+jquery组合验证注册用户是否存在
2014/04/30 Javascript
jQuery中bind()方法用法实例
2015/01/19 Javascript
JS获取当前脚本文件的绝对路径
2016/03/02 Javascript
jQuery判断checkbox选中状态
2016/05/12 Javascript
jQuery 获取跨域XML(RSS)数据的相关总结分析
2016/05/18 Javascript
JS简单实现仿百度控制台输出信息效果
2016/09/04 Javascript
jquery radio的取值_radio的选中_radio的重置方法
2016/09/20 Javascript
浅谈JS中String()与 .toString()的区别
2016/10/20 Javascript
jQuery操作复选框(CheckBox)的取值赋值实现代码
2017/01/10 Javascript
jQuery监听浏览器窗口大小的变化实例
2017/02/07 Javascript
jQuery在header中设置请求信息的方法
2017/03/06 Javascript
利用jQuery实现简单的拖曳效果实例代码
2017/10/20 jQuery
js实现简单数字变动效果
2017/11/06 Javascript
[02:45]DOTA2英雄敌法师基础教程
2013/11/25 DOTA
以Flask为例讲解Python的框架的使用方法
2015/04/29 Python
Python3实现从指定路径查找文件的方法
2015/05/22 Python
pyqt 实现QlineEdit 输入密码显示成圆点的方法
2019/06/24 Python
Django获取该数据的上一条和下一条方法
2019/08/12 Python
TensorFlow dataset.shuffle、batch、repeat的使用详解
2020/01/21 Python
python 比较字典value的最大值的几种方法
2020/04/17 Python
利用Python实现字幕挂载(把字幕文件与视频合并)思路详解
2020/10/21 Python
S’well Bottle保温杯官网:绝缘不锈钢水瓶
2018/05/09 全球购物
凌阳科技股份有限公司C++程序员面试题笔试题
2014/11/20 面试题
党性观念心得体会
2014/09/03 职场文书
大一新生检讨书
2014/10/29 职场文书
2014年教研工作总结
2014/12/06 职场文书
给老师的一封感谢信
2015/01/20 职场文书
创业计划之特色精品店
2019/08/12 职场文书
Python+pyaudio实现音频控制示例详解
2022/07/23 Python