123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- <?php
- namespace addons\crontab\library;
- use fast\Http;
- use think\Config;
- use think\Db;
- class CommandRunnable implements \Jenner\SimpleFork\Runnable
- {
- protected $connect = null;
- protected $crontab = null;
- public function __construct($crontab)
- {
- $this->crontab = $crontab;
- }
- public function run()
- {
- $processId = getmypid();
- //这里需要强制重连数据库,使用已有的连接会报2014错误
- $this->connect = Db::connect([], true);
- $this->connect->execute("SELECT 1");
- $message = '';
- $result = false;
- $this->crontabLog = null;
- $log = [
- 'crontab_id' => $this->crontab['id'],
- 'executetime' => time(),
- 'completetime' => null,
- 'content' => '',
- 'processid' => $processId,
- 'status' => 'inprogress',
- ];
- $this->connect->name("crontab_log")->insert($log);
- $this->crontabLogId = $this->connect->getLastInsID();
- try {
- if ($this->crontab['type'] == 'url') {
- if (substr($this->crontab['content'], 0, 1) == "/") {
- // 本地项目URL
- $message = shell_exec('php ' . ROOT_PATH . 'public/index.php ' . $this->crontab['content']);
- $result = (bool)$message;
- } else {
- $arr = explode(" ", $this->crontab['content']);
- $url = $arr[0];
- $params = $arr[1] ?? '';
- $method = $arr[2] ?? 'POST';
- try {
- // 远程异步调用URL
- $ret = Http::sendRequest($url, $params, $method);
- $result = $ret['ret'];
- $message = $ret['msg'];
- } catch (\Exception $e) {
- $message = $e->getMessage();
- }
- }
- } elseif ($this->crontab['type'] == 'sql') {
- $ret = $this->sql($this->crontab['content']);
- $result = $ret['ret'];
- $message = $ret['msg'];
- } elseif ($this->crontab['type'] == 'shell') {
- // 执行Shell
- $message = shell_exec($this->crontab['content']);
- $result = !is_null($message);
- }
- } catch (\Exception $e) {
- $message = $e->getMessage();
- }
- //设定任务完成
- $this->connect->name("crontab_log")->where('id', $this->crontabLogId)->update(['content' => $message, 'completetime' => time(), 'status' => $result ? 'success' : 'failure']);
- }
- /**
- * 执行SQL语句
- */
- protected function sql($sql)
- {
- // 执行SQL
- $sqlquery = str_replace('__PREFIX__', config('database.prefix'), $sql);
- $sqls = preg_split("/;[ \t]{0,}\n/i", $sqlquery);
- $result = false;
- $message = '';
- $this->connect->startTrans();
- try {
- foreach ($sqls as $key => $val) {
- if (trim($val) == '' || substr($val, 0, 2) == '--' || substr($val, 0, 2) == '/*') {
- continue;
- }
- $message .= "\nSQL:{$val}\n";
- $val = rtrim($val, ';');
- if (preg_match("/^(select|explain)(.*)/i ", $val)) {
- $count = $this->connect->execute($val);
- if ($count > 0) {
- $resultlist = Db::query($val);
- } else {
- $resultlist = [];
- }
- $message .= "Total:{$count}\n";
- $j = 1;
- foreach ($resultlist as $m => $n) {
- $message .= "\n";
- $message .= "Row:{$j}\n";
- foreach ($n as $k => $v) {
- $message .= "{$k}:{$v}\n";
- }
- $j++;
- }
- } else {
- $count = $this->connect->getPdo()->exec($val);
- $message = "Affected rows:{$count}";
- }
- }
- $this->connect->commit();
- $result = true;
- } catch (\PDOException $e) {
- $message = $e->getMessage();
- $this->connect->rollback();
- $result = false;
- }
- return ['ret' => $result, 'msg' => $message];
- }
- }
|