php think cron,THINKPHP的cron计划任务的实现

写一个cli的入口文件

cli.php

define(‘MODE_NAME‘, ‘cli‘);

// 检测PHP环境

if(version_compare(PHP_VERSION,‘5.3.0‘,‘ 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

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 模型

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 模型

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;

}

}

原文:http://my.oschina.net/xinson/blog/416652

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值