THINKPHP的cron计划任务的实现

写一个cli的入口文件

cli.php

<?php
define(‘MODE_NAME‘, ‘cli‘);
// 检测PHP环境
if(version_compare(PHP_VERSION,‘5.3.0‘,‘<‘))  die(‘require PHP > 5.3.0 !‘);

define(‘APP_DEBUG‘, true);

// 定义应用目录
define(‘APP_PATH‘, __DIR__ . ‘/Application/‘);

// 引入ThinkPHP入口文件
require __DIR__ . ‘/ThinkPHP/ThinkPHP.php‘;

写一个执行文件

cron.php

define(‘AUTO_CRON‘, true);
include __DIR__ . ‘/cli.php‘;

数据库设计

DROP TABLE IF EXISTS `cron`;
CREATE TABLE IF NOT EXISTS `cron` (
  `cron_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT ‘‘,
  `expression` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT ‘‘,
  `class` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT ‘‘,
  `method` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT ‘‘,
  `type` varchar(30) COLLATE utf8_unicode_ci NOT NULL DEFAULT ‘‘,
  `status` varchar(30) COLLATE utf8_unicode_ci NOT NULL DEFAULT ‘‘,
  `created_at` timestamp NOT NULL DEFAULT ‘0000-00-00 00:00:00‘,
  `updated_at` timestamp NOT NULL DEFAULT ‘0000-00-00 00:00:00‘,
  `run_at` timestamp NULL DEFAULT NULL,
  `ms` int(10) unsigned NOT NULL DEFAULT ‘0‘,
  `error` text COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`cron_id`),
  KEY `name` (`name`,`created_at`),
  KEY `cron_status_index` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;

执行文件 init.php

/写个hook程序执行init.php

<?php
use Think\Log, Think\Db, Cron\Model\Cron;
$Model = new \Think\Model();
$Has = !$Model->query("SHOW TABLES LIKE ‘cron‘")?false:true;

if(defined("AUTO_CRON") && $Has){
    class CronCommand
    {

        protected $_initializedJobs;
        protected $_jobs;
        protected $_now;

        public function __construct()
        {
            $this->_now = strtotime(date(‘Y-n-j H:i‘));
            import("Cron.Common.Cron.tdcron_entry",‘‘,‘.php‘);
            import("Cron.Common.Cron.tdcron",‘‘,‘.php‘);
        }

        /**
         * 这里是放要执行的代码
         */
        public function fire()
        {
            restore_error_handler();
            restore_exception_handler();
            $this->_initializedJobs = array();
            $jobs = M(‘cron‘)->where("status = ‘initialized‘")->select();
            /**
             * @var $cron Cron
             * 已存在 cron
             */
            if($jobs) {
                $cron = new Cron();
                foreach ($jobs as $data) {
                    $cron->setData($data)->isNew(false);
                    $this->_initializedJobs[$data[‘name‘]] = $cron;
                }
            }

            /**
             * 新 cron
             */
            foreach ($this->getCronJobs() as $name => $cronJob) {
                if (isset($cronJob[‘expression‘])) {
                    $expression = $cronJob[‘expression‘];
                } else {
                    Log::write(‘Cron expression is required for cron job "‘ . $name . ‘"‘,Log::WARN);
                    continue;
                }
                if ($this->_now != tdCron::getNextOccurrence($expression, $this->_now)) continue;
                $cronJob[‘name‘] = $name;
                $cron = isset($this->_initializedJobs[$name]) ? $this->_initializedJobs[$name] : $this->_initializedJobs[$name] = new Cron();
                $cron->initialize($cronJob);
            }

            /* @var $cron Cron 处理*/
            foreach ($this->_initializedJobs as $cron) {
                $cron->run();
            }

        }

        /**
         * Get All Defined Cron Jobs
         * 获取配置
         * @return array
         */
        public function getCronJobs()
        {
            if ($this->_jobs === null) {
                $this->_jobs = C(‘beastalkd‘);
            }
            return $this->_jobs;
        }

    }
    $command = new CronCommand();
    $command->fire();
}

cron 模型

<?php
namespace Cron\Model;
use Common\Model;
use Think\Log;

/**
 * Class Cron
 * @method string getClass()
 * @method string getMethod()
 * @method string getName()
 * @method string getType()
 * @package Cron\Model
 */
class Cron extends Model{

    const STATUS_COMPLETED = ‘completed‘;
    const STATUS_FAILED = ‘failed‘;
    const STATUS_INITIALIZED = ‘initialized‘;
    const STATUS_RUNNING = ‘running‘;

    protected $name = ‘cron‘;
    protected $tableName = ‘cron‘;
    protected $pk = ‘cron_id‘;

    protected $_originalData = array();
    /**
     *  保存配置信息CLASS
     */
    protected static $_cron_classes = array();

    /**
     * @param $class
     * @return mixed  获取配置的 CLASS
     */
    public function getSingleton($class)
    {
        isset(static::$_cron_classes[$class]) or static::$_cron_classes[$class] = new $class;
        return static::$_cron_classes[$class];
    }

    /**
     * @param $cronJob
     * @return $this
     * 初始化 任务状态
     */
    public function initialize($cronJob)
    {
        foreach ($cronJob as $k => $v) {
            $this->setData($k, $v);
        }
        $now = date(‘Y-m-d H:i:s‘);
        $this->setData(‘status‘,self::STATUS_INITIALIZED)->setData(‘created_at‘,$now)->setData(‘updated_at‘,$now)->save();
        return $this;
    }

    /**
     * @return $this  run 命令
     */
    public function run()
    {
        $this->setData(‘run_at‘,date(‘Y-m-d H:i:s‘))->setData(‘status‘,self::STATUS_RUNNING)->save();
        Timer::start();
        try {
            $class = $this->getData(‘class‘);
            $method = $this->getData(‘method‘);
            if (!class_exists($class)) throw new \Exception(sprintf(‘Class "%s" not found!‘, $class));
            if (!method_exists($class, $method)) throw new \Exception(sprintf(‘Method "%s::%s()" not found!‘, $class, $method));
            $callback = array($this->getSingleton($class), $method);

            //new CLASS 使用操作方法
            call_user_func($callback);
            Timer::stop();
            $this->setData(‘ms‘,round(Timer::diff() * 1000))->setData(‘status‘,self::STATUS_COMPLETED)->save();

        } catch (\Exception $e) {
            Timer::stop();
            $this->setData(‘ms‘,round(Timer::diff() * 1000))
                ->setData(‘status‘,self::STATUS_FAILED)
                ->setData(‘error‘,$e->getMessage() . "\nParams:\n" . var_export($this->getDbFields(), true))->save();
            Log::write($e->getMessage() . "\n" . $e->getTraceAsString(),Log::ERR);
        }
        return $this;
    }

}

Common\Model 模型

<?php

namespace Common;

use Think\Model as ThinkModel;

/**
 * Class Model
 * @package Common
 *
 * @property \Think\Db\Driver\Mysql $db DB instance
 */
abstract class Model extends ThinkModel {
   protected $_isNew = true;
   protected $_jsonFields = array();
   protected $_originalData = array();

   protected function _after_find(&$result, $options) {
      foreach ($this->_jsonFields as $field) {
         is_string($_data = fnGet($result, $field)) and $result[$field] = json_decode($_data, true);
      }
      $this->_originalData = $result;
      $this->_isNew = !$result;
      parent::_after_find($result, $options);
   }

   protected function _after_save($result) {
   }

   protected function _before_find() {
      $this->_originalData = array();
   }

   protected function _facade($data) {
      foreach ($this->_jsonFields as $field) {
         is_array($_data = fnGet($data, $field)) and $data[$field] = json_encode($_data);
      }
      return parent::_facade($data);
   }

   public function find($options = array()) {
      $this->_before_find();
      return parent::find($options);
   }

   public function getData($key = null) {
      return $key === null ? $this->data : $this->__get($key);
   }

   public function getOptions() {
      return $this->options;
   }

   public function getOriginalData($key = null) {
      return $key === null ? $this->_originalData : fnGet($this->_originalData, $key);
   }

   /**
    * Get or set isNew flag
    *
    * @param bool $flag
    *
    * @return bool
    */
   public function isNew($flag = null) {
      if ($flag !== null) $this->_isNew = (bool)$flag;
      return $this->_isNew;
   }

   public function save($data = ‘‘, $options = array()) {
      if ($this->_isNew) {
         $oldData = $this->data;
         $result = $this->add($data, $options);
         $this->data = $oldData;
         if ($result && $this->pk && is_string($this->pk)) {
            $this->setData($this->pk, $result);
         }
         $this->_isNew = false;
      } else {
         $oldData = $this->data;
         $result = parent::save($data, $options);
         $this->data = $oldData;
      }
      $this->_after_save($result);
      return $result;
   }

   public function setData($key, $value = null) {
      is_array($key) ?
         $this->data = $key :
         $this->data[$key] = $value;
      return $this;
   }
}
时间: 2024-10-12 02:17:31

THINKPHP的cron计划任务的实现的相关文章

【黑马Android】(13)Linux操作系统/cron计划任务

Oracle VM VirtualBox Centos cron计划任务: 命令示例: Cat 1.txt Tac 1.txt Find / -name profile Ps -ef | grep python Netstat -ano | more

管理用户和组,NTP,cron计划任务

1.管理用户和组 1.1 基本概念 用户账户的作用:登陆操作系统.访问控制(不同的用户具备不同的权限) 组帐号:方便对用户的管理 唯一标识: UID  GID 管理员的UID:0 普通用户UID:RHEL7从1000开始 组的分类: 附加组(从属组.公共组)      基本组(私有组) 1.2 添加用户 用户基本信息存放在 /etc/passwd 文件 [[email protected] ~]# head -1 /etc/passwd root:x:0:0:root:/root:/bin/ba

Admin(四)——NTP、tar、cron计划任务

一.管理用户和组--用户账户的作用:登录操作系统.访问控制(不同的用户具备不同的权限)--组账号:方便对用户的管理--唯一标识: UID(用户ID).GID(组ID)管理员的UID为0,普通用户的UID从1000开始(rhel7)组的分类:附加组(从属组.公共组)和基本组(私有组)linux 用户要求一个用户至少属于一个组,例如创建一个用户lisi,默认情况下会创建一个lisi组.--用户的基本信息存放在/etc/passwd文件中,文件中每一行是每个用户的信息,每个字段的意思:root:x:0

linux的定cron计划任务命令

为当前用户创建cron服务 1.  键入 crontab  -e 编辑crontab服务文件 例如 文件内容如下: */2 * * * * /bin/sh /home/admin/jiaobeny/deleteFile.sh 保存文件并并退出 */2 * * * * /bin/sh /home/admin/jiaobeny/deleteFile.sh */2 * * * * 通过这段字段可以设定什么时候执行脚本 /bin/sh /home/admin/jiaobeny/deleteFile.sh

linux cron 计划任务常用符号总结

[[email protected] ~]# crontab --help crontab: invalid option -- '-' crontab: usage error: unrecognized option usage: crontab [-u user] file crontab [-u user] [ -e | -l | -r ] (default operation is replace, per 1003.2) -e (edit user's crontab) 编辑cron

Linux cron 计划任务日志跟踪

场景:  需要在系统的cron中启动一个计划任务,跑的是一个shell脚本,脚本中大致意思是切换至 abc用户执行一个php文件(例如: /data/soft/auto.php),那么现在问题来了,脚本的内 容如下: #!/bin/bash sudo -u abc /data/soft/auto.php echo ' >>> auto success !!! ' 你会神奇的发现,系统的/var/log/cron日志中已经显示auto success,但是这个程序依然 是没有执行,你怎么知

linux cron计划任务

$ crontab -e 例如:每天两点钟执行 0 2 */1 * * /usr/bin/python /www/tbktsh/sendms.py &> /dev/null 01 * * * * root run-parts /etc/cron.hourly  # 每小时执行/etc/cron.hourly内的脚本,"run-parts"这个参数是指执行文件夹下的所有文件,不加此参数则需要给出明确的执行脚本文件. $ service crond restart  or  

Linux中的cron计划任务配置方法(详细)

cron来源于希腊单词chronos(意为“时间”),指Linux系统下一个自动执行指定任务的程序(计划任务) 1. crontab命令选项 #crontab -u <-l, -r, -e> -u指定一个用户-l列出某个用户的任务计划-r删除某个用户的任务-e编辑某个用户的任务 2. cron文件语法与写法 可用crontab -e命令来编辑,编辑的是/var/spool/cron下对应用户的cron文件,也可以直接修改/etc/crontab文件.具体格式如下: Minute Hour Da

cron计划任务、chkconfig工具、systemd管理服务、unit、target介绍

1. linux任务计划cron linux的大部分系统管理工作都是通过定期自动执行某个脚本来完成的,那么如何定期执行某个脚本呢?这就要借助linux的cron功能了,这部分的内容很重要,请牢记! 命令crontab linux的任务计划功能的操作都是通过crontab命令来完成的,其常用的选项有以下几个: -u:表示指定某个用户,不加-u选项则为当前用户. -e:表示制定计划任务 -l:表示列出计划任务 -r:表示删除计划任务 任务计划的配置文件: # cat /etc/crontab SHE