定时脚本基类
<?php
/**
* 执行cron基类
*
* @author huangmin<andhm@126.com>
* @version $Id$
* @since 1.0
*/
abstract class BaseCron
{
/**
* cron文件路径
* @var string
*/
protected $cronFile;
/**
* 脚本开始时间
* @var int
*/
protected $startTime;
/**
* 脚本结束时间
* @var int
*/
protected $endTime;
/**
* 脚本执行状态
* @var int
*/
protected $status;
/*
* 数据库连接
*/
protected $dbConnection;
/**
* 需要关注的结果描述
* @var string
*/
protected $attention = [];
/**
* 当前cron执行的记录ID
* @var int
*/
private $cronLogId;
CONST CRON_STATUS_SUCC = 1; // 脚本执行状态,成功
CONST CRON_STATUS_FAIL = 2; // 脚本执行状态,失败
/**
* 构造方法
* @param string $cronDesc cron用途描述
* @param string $cronFile cron文件路径
*/
public function __construct($cronFile = __FILE__)
{
if (defined('AG_DOC_ROOT')) {
$cronFile = str_replace(AG_DOC_ROOT, '', $cronFile);
}
Context::getInstance()->initialize();
$this->dbConnection = Propel::getConnection();
$this->cronFile = $cronFile;
$this->status = self::CRON_STATUS_SUCC; // 默认状态是 成功
}
/**
* 获取数据库连接
* @return Connection
*/
public function getDBConnection()
{
return $this->dbConnection;
}
/**
* 业务脚本执行核心逻辑
* @return void
*/
abstract protected function run();
/**
* 脚本执行流程
* @return void
*/
public function runAll()
{
$this->beforeRun();
// 捕获异常
$this->errorHandler();
try {
$this->run();
} catch (Exception $ex) {
$this->status = self::CRON_STATUS_FAIL;
$this->setAttention('errormsg:' . $ex->getMessage() . ', line:' . $ex->getLine() . ', traceinfo:' . $ex->getTraceAsString());
}
$this->afterRun();
}
/**
* 脚本执行之前处理逻辑
* @return void
*/
protected function beforeRun()
{
$this->startTime = time();
$sql = 'insert into t_cron_log set cron_file=?,start_time=?,status=0';
$smtm = $this->dbConnection->prepareStatement($sql);
$smtm->executeUpdate([$this->cronFile, $this->startTime]);
$this->cronLogId = mysql_insert_id();
// TODO
// 执行cron之前,写入t_cron_log执行记录
// 需要写入的字段有:cron_file,start_time
// 写入db后,需要获取到 记录的 主键ID, $this->cronLogId = ${主键ID}
}
/**
* 脚本执行之后处理逻辑
* @return void
*/
protected function afterRun()
{
$attention = implode(',', $this->attention);
$this->endTime = time();
$sql = 'update t_cron_log set status=?,attention=?,end_time=? where log_id=?';
$smtm = $this->dbConnection->prepareStatement($sql);
$smtm->executeUpdate([$this->status, $attention, time(), $this->cronLogId]);
// TODO
// 更新t_cron_log记录
// 需要更新的字段有:end_time,status
// 更新条件是 主键ID = $this->cronLogId
}
/**
* fatal 错误捕获
* @return void
*/
protected function errorHandler()
{
$objCron = $this;
register_shutdown_function(function () use ($objCron) {
$errorInfo = error_get_last();
$fatal = E_ERROR | E_USER_ERROR | E_CORE_ERROR |
E_COMPILE_ERROR | E_RECOVERABLE_ERROR | E_PARSE;
if (!empty($errorInfo) && ($errorInfo['type'] === ($errorInfo['type'] & $fatal))) {
$objCron->status = self::CRON_STATUS_FAIL;
$objCron->setAttention('errormsg:' . $errorInfo['message'] . ', line:' . $errorInfo['line']);
$objCron->afterRun();
}
});
}
protected function setAttention($v)
{
$this->attention[] = $v;
}
protected function setSuccess()
{
$this->status = self::CRON_STATUS_SUCC;
}
protected function setFail()
{
$this->status = self::CRON_STATUS_FAIL;
}
protected function doChangeLog($table,$column,$from,$to,$pk,$id)
{
$data = [];
$data['table'] = $table;
$data['column'] = $column;
$data['from'] = $from;
$data['to'] = $to;
$data[$pk] = $id;
$str = json_encode($data)."\n";
file_put_contents(AG_DOC_ROOT . '/var/logs/http_to_https/dbconvert.log',$str, FILE_APPEND);
}
}