吴峰的博客

1.在服务器增加一个每分钟执行的任务(入口文件)

* * * * *  php root/****/Crontab.php 1 

2.创建入口文件Crontab.php

//设备ID,服务器的设备编号

$device_id = $_SERVER['argv'][1];

if(!$device_id){

    exit("缺少设备ID参数");

}

$crontab = new CrontabModel($device_id);

$crontab->actionRun();


3.创建CrontabModel文件,其中的配置文件可以提出来,配置在数据库中。

class CrontabModel

{

    //当前服务器的命令集合

    private $cronJobs = [];

    //所有服务器的命令集合

    private $all_Jobs = [];

    public function __construct($device_id)

    {

         $all_Jobs = array(

'1' => array(//设备1

'cronJobs' => array(

'sleep 10; ***/php ***.php' => '*/30 * * * *',

'***/php ***.php' => '*/30 * * * *',

),

),

'2' => array(//设备2

'cronJobs' => array(

'sleep 10; ***/php ***.php' => '*/30 * * * *',

'***/php ***.php' => '*/30 * * * *',

),

),

);

        $this->cronJobs = $all_Jobs[$device_id]['cronJobs'];

    }



    public function actionRun()

    {

        // 格式化当前时间戳并转成 分 时 日 月 周 格式

        /*

        |i  有前导零的分钟数 00 到 59>

        |G  小时,24 小时格式,没有前导零 0 到 23

        |j  月份中的第几天,没有前导零 1 到 31

        |n  数字表示的月份,没有前导零 1 到 12

        |w  星期中的第几天,数字表示 0(表示星期天)到 6(表示星期六)

        */

        $now = explode(' ', date('i G j n w', time()));

        $raw = $this->parseCron($this->cronJobs);

        foreach ($raw as $command => $cron) {

            // 上面已经列出了所有的情况,所以当前时间循环时如果有一项不符合则不能向下执行

            foreach ($now as $k => $piece) {

                if (!in_array($piece, $raw[$command][$k])) {

                    continue 2;

                }

            }

            // 下面是调用系统函数执行shell命令

            $this->runCommandBackground($command);

        }

    }



    /**

     * 解析需要执行的命令

     * @param $cronJobs

     * @return array

     */

    public function parseCron($cronJobs)

    {

        // 解析后的数组

        $raw = [];

        foreach ($cronJobs as $command => $cron) {

            // $command -> hello/index  $cron -> */5 * * * *

            // 将命令用空格分割成数组

            $cronArr = explode(' ', $cron, 5); // ['*/5', '*', '*', '*', '*']

            // 针对每一个位置进行解析

            $dimensions = array(

                array(0, 59), //Minutes

                array(0, 23), //Hours

                array(1, 31), //Days

                array(1, 12), //Months

                array(0, 6),  //Weekdays

            );

            foreach ($cronArr as $key => $item) {

                // 标记是哪种命令格式,通过使用的crontab命令可以分为两大类

                // 1.每几分钟或每小时这样的 */10 * * * *

                // 2.几点几分这样的 10,20,30-50 * * * *

                list($repeat, $every) = explode('/', $item, 2) + [false, 1];

                if ($repeat === '*') {

                    $raw[$command][$key] = range($dimensions[$key][0], $dimensions[$key][1]);

                } else {

                    // 处理逗号拼接的命令

                    $tmpRaw = explode(',', $item);

                    foreach ($tmpRaw as $tmp) {

                        // 处理10-20这样范围的命令

                        $tmp = explode('-', $tmp, 2);

                        if (count($tmp) == 2) {

                            $raw[$command][$key] = array_merge($raw[$command][$key], 

range($tmp[0], $tmp[1]));

                        } else {

                            $raw[$command][$key][] = $tmp[0];

                        }

                    }

                }

                // 判断*/10 这种类型的

                if ($every > 1) {

                    foreach ($raw[$command][$key] as $k => $v) {

                        if ($v % $every != 0) {

                            unset($raw[$command][$key][$k]);

                        }

                    }

                }

            }

        }

        return $raw;

    }



    /**

     * 以守护进程模式执行命令

     * @param $command

     */

    public function runCommandBackground($command)

    {

        echo "执行";

        echo $command;

        system($command . ' &');

    }

}

Tags:
PHP
评论 (0)
    说点什么吧... (取消回复)

    正在加载验证码......

    请先拖动验证码到相应位置

Copyright 吴峰的博客 © 2014-2016 管理员邮箱:phpwufeng@163.com   统计:   ICP备案:鲁ICP备16004939号-1