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 相关文章推荐
如何将一个表单同时提交到两个地方处理
Oct 09 PHP
解析dedeCMS验证码的实现代码
Jun 07 PHP
PHP反射机制用法实例
Aug 28 PHP
ThinkPHP数据操作方法总结
Sep 28 PHP
在WordPress的文章编辑器中设置默认内容的方法
Dec 29 PHP
php面向对象之反射功能与用法分析
Mar 29 PHP
thinkPHP5 tablib标签库自定义方法详解
May 10 PHP
php写一个函数,实现扫描并打印出自定目录下(含子目录)所有jpg文件名
May 26 PHP
阿里云Win2016安装Apache和PHP环境图文教程
Mar 11 PHP
php打开本地exe程序,js打开本地exe应用程序,并传递相关参数方法
Feb 06 PHP
网站被恶意镜像怎么办 php一段代码轻松搞定(全面版)
Oct 23 PHP
PHP simplexml_load_file()函数讲解
Feb 03 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中处理模拟rewrite 效果
2006/12/09 PHP
Yii核心组件AssetManager原理分析
2014/12/02 PHP
PHP开发中AJAX技术的简单应用
2015/12/11 PHP
Symfony实现行为和模板中取得request参数的方法
2016/03/17 PHP
PHP之多条件混合筛选功能的实现方法
2019/10/09 PHP
PHP常见的序列化与反序列化操作实例分析
2019/10/28 PHP
让div层随鼠标移动的实现代码 ie ff
2009/12/18 Javascript
JavaScript 数组详解
2013/10/10 Javascript
各种页面定时跳转(倒计时跳转)代码总结
2013/10/24 Javascript
JavaScript引用类型和基本类型详解
2016/01/06 Javascript
JavaScript中循环遍历Array与Map的方法小结
2016/03/12 Javascript
JQuery在循环中绑定事件的问题详解
2016/06/02 Javascript
基于BootStrap实现局部刷新分页实例代码
2016/08/08 Javascript
jqgrid实现简单的单行编辑功能
2017/09/30 Javascript
浅谈es6中export和export default的作用及区别
2018/02/07 Javascript
微信小程序wepy框架学习和使用心得详解
2019/05/24 Javascript
js全屏事件fullscreenchange 实现全屏、退出全屏操作
2019/09/17 Javascript
layui 实现表格某一列显示图标
2019/09/19 Javascript
jquery validate 实现动态增加/删除验证规则操作示例
2019/10/28 jQuery
vue中template的三种写法示例
2020/10/21 Javascript
Python中动态获取对象的属性和方法的教程
2015/04/09 Python
Tensorflow实现卷积神经网络的详细代码
2018/05/24 Python
如何在python字符串中输入纯粹的{}
2018/08/22 Python
Python寻找两个有序数组的中位数实例详解
2018/12/05 Python
python实现向微信用户发送每日一句 python实现微信聊天机器人
2019/03/27 Python
Python facenet进行人脸识别测试过程解析
2019/08/16 Python
在Python中用GDAL实现矢量对栅格的切割实例
2020/03/11 Python
新书吧创业计划书
2014/01/31 职场文书
《黄山奇石》教学反思
2014/04/19 职场文书
2015年元旦演讲稿
2014/09/12 职场文书
领导个人查摆剖析材料
2014/10/29 职场文书
2019奶茶店创业计划书范本!
2019/07/15 职场文书
Redis Cluster 字段模糊匹配及删除
2021/05/27 Redis
Spring boot应用启动后首次访问很慢的解决方案
2021/06/23 Java/Android
python geopandas读取、创建shapefile文件的方法
2021/06/29 Python
Python识别花卉种类鉴定网络热门植物并自动整理分类
2022/04/08 Python