php——实现linux的定时任务

  在php学习和工作生活中,经常需要定时去执行任务,一般可以分为纯代码实现和借助linux的定时任务管理器cron.d或者crontab来实现。

  1.先来说一下纯代码是如何实现的。

<?php 
ignore_user_abort();//关闭浏览器仍然执行
set_time_limit(0);//让程序一直执行下去
$interval=3;//每隔一定时间运行 3代表3s
do{
    $msg=date("Y-m-d H:i:s");
    file_put_contents("log.log",$msg,FILE_APPEND);//记录日志
    sleep($interval);//等待时间,进行下一次操作。
}while(true);
?>

这是一个基本的定时器,但是这个定时器有一个缺陷,因为while的判定条件是true,一旦这个程序执行就不可控制了,除非重启服务器或者关机,非常麻烦。现在可以加入一个控制条件,来控制这个定时器的开与关。

新建一个controller.php

<?php
return 1;//1执行脚本 0退出执行脚本
?>

定时器timer.php改为

<?php
    ignore_user_abort();//关闭浏览器后,继续执行php代码
    set_time_limit(0);//程序执行时间无限制
    $sleep_time = 5;//多长时间执行一次
    $switch = include 'switch.php';
    while($switch){
        $switch = include 'switch.php';
        $msg=date("Y-m-d H:i:s").$switch;
            file_put_contents("log.log",$msg,FILE_APPEND);//记录日志
        sleep($sleep_time);//等待时间,进行下一次操作。
    }
    exit();
    
?>

这就是纯代码实现定时任务的基本方法了,但是存在局限性。现在再来介绍一下linux的定时任务管理器,cron.d或者crontab。

2.cron.d增加定时任务

当我们要增加全局性的计划任务时,一种方式是直接修改/etc/crontab。但是,一般不建议这样做,/etc/cron.d目录就是为了解决这种问题而创建的。

例如,增加一项定时的备份任务,我们可以这样处理:在/etc/cron.d目录下新建文件backup.sh,内容如下:

    # m h dom mon dow user command

    * 1 * * * root /sbin/mon_zetc_logtar.sh

cron进程执行时,就会自动扫描该目录下的所有文件,按照文件中的时间设定执行后面的命令。

cron执行时,也就是要读取三个地方的配置文件:一是/etc/crontab,二是/etc/cron.d目录下的所有文件,三是每个用户的配置文件。

所以在我们就可以使用php代码中在/etc/cron.d目录下新建*.sh文件,然后将定时任务写入*.sh文件中,这样就完成了cron.d增加定时任务。

3.crontab增加定时任务

一般,使用crontab -e命令来编辑定时任务列表,将定时任务写入列表中。

如何用php代码设置crontab,具体看下面代码例子。

<?php
    /*
        Filename: PhpCrontab.php
        Comment: php 控制linux crontab 命令
        User: lxd
        Time: 15/11/13 13:55
    */

    class PhpCrontab {
        private $_crontab_obj       = null;


        //构造 引入 是放在同一个目录里面的 
        public function __construct() {
            set_include_path(get_include_path() . PATH_SEPARATOR . __DIR__);
            spl_autoload_register(function($class_name) {
                //需要将引入的文件全部小写
                spl_autoload($class_name,'.php');
            });
            $this->_crontab_obj    = new CrontabManager();
        }


        /*
         * 新增任务
         *  @param  id  任务唯一标示符,自己数据库的,方便自己后期处理
         *  @param time 任务执行时间
         *  @param job  任务具体内容
         *
         *  @return false | 任务自身的id标志
         */
        public function addJob($id,$time,$job) {
            //新增任务
            $job_obj            = $this->_crontab_obj->newJob();
            $job_obj->on($time)->addComments(array($id))->doJob($job);
            $this->_crontab_obj->add($job_obj);
            $this->_crontab_obj->save();
            $job_obj            = $time = null;

            //获取任务列表
            $job_arr            = $this->getJobList();
            //通过$id 找到任务的自身id
            foreach($job_arr as $k => $v) {
                //正则匹配
                $pattern        = '/#\s[\w]+(\s|$)/iU';
                $match_info     = array();
                $is_match       = preg_match_all($pattern,$v,$match_info);
                if(!$is_match)
                    return false;

                if(trim($match_info[0][0]) == '# ' . $id)
                    return str_replace("\n",'',$match_info[0][1]);

            }

            return false;
        }


        /*
         * 获取任务列表
         * @param   void
         * @return  array
         */
        public function getJobList() {
            //获取字符串任务列表
            $job_str        = $this->_crontab_obj->listJobs();
            //解析为数组,返回
            return explode("\n\n",$job_str);
        }

        /*
         * 清理一条任务
         * @param  任务自身的id
         * @return true | false
         */
        function deleteJob($job = null) {
        $jobsDeleted = 0;
        if (!is_null($job)) {
            $data = array();
            $oldJobs = explode("\n", $this->listJobs()); // get the old jobs

            if (is_array($oldJobs)) {
                //放置comment 信息
                $_comment        = '';
                foreach ($oldJobs as $oldJob) {
                    if ($oldJob != '') {
                        //加入判断,匹配出comment信息
                        if(preg_match_all('/^#(.*)/',$oldJob,$match_arr)) {
                            $_comment       = $match_arr[0][0];
                            continue;
                        }

                        if (!preg_match('/' . $job . '/', $oldJob)) {
                            $newJob = new CronEntry($oldJob, $this);
                            $newJob->lineComment = '';
                            //设置comment 信息
                            $newJob->comments    = array($_comment);
                            $_comment            = '';

                            $data[] = $newJob;
                        } else {
                            $jobsDeleted++;
                        }
                    }
                }
            }
            $this->jobs = $data;
        }
        return $jobsDeleted;
    }



        /*
         * 析构
         */
        public function destruct() {
            $this->_crontab_obj         = null;
        }

    }

 然后在需要操作crontab的地方引用该文件,实例化类,新增定时任务就可以了。希望可以帮到大家,谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值