| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 | <?phpnamespace 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];    }}
 |