/** * 执行方法 */ public function handleRequest() { $request = \H2O::getContainer('request'); //获取HTTP请求组件 $route = $request->getRoute(); $module = \H2O::getContainer('module'); return $module->runAction($route); }
/** * 运行实例 */ public function run() { $configs = \H2O::getAppConfigs(); if (isset($configs['boot']) && !empty($configs['boot']) && is_array($configs['boot'])) { //加载引导程序 $this->_boot($configs['boot']); } $res = $this->handleRequest(); $debug = $configs['debug']; if ($debug === true) { //debug $logger = \H2O::getContainer('logger'); $logger->debugger($this->runExpend()); //记录运行状态 } echo $res; }
/** * 执行方法 */ public function handleRequest() { $request = \H2O::getContainer('request'); //控制台请求 $route = $request->getRoute(); if (strncmp($route['controller'], '@', 1) === 0) { //当有前缀@时为,则为系统控制台模块 $sclass = '\\H2O\\console\\' . ucfirst(substr($route['controller'], 1)); $o = \H2O::createObject($sclass); $action = 'act' . ucfirst($route['action']); if (method_exists($o, $action)) { call_user_func([$o, $action]); } else { throw new \Exception($sclass . ' no method:' . $action); } } else { $module = \H2O::getContainer('module'); return $module->runAction($route); } }
/** * 写入debugger日志 * @param array $data 消耗信息 */ public function debugger($data) { $request = \H2O::getContainer('request'); Stdout::title('Debugger Info ' . date('Y-m-d H:i:s')); Stdout::table([['Route', 'RunTime', 'Memory'], [$request->getRequestUri(), $data['runtime'], $data['memory']]]); $logfile = APP_RUNTIME . DS . 'console' . DS . 'debugger' . DS . date('Ymd') . '.log'; //异常日志文件 $content = Stdout::get(); //内容 H2O\helpers\File::write($logfile, $content); //写入日志信息 }
/** * 翻页数据 * @param int $size 每页显示条数 * @param string $param 翻页参数名 * @return array */ public function pageData($size = 20, $param = 'page') { $request = \H2O::getContainer('request'); //获取当前页 $cpage = $request->get($param); $cpage = empty($cpage) ? 1 : intval($cpage); $cpage = $cpage < 1 ? 1 : $cpage; $sql = $this->getRawSql(); //获取解析后的SQL $total = $this->rowCount($sql); //总记录数 $data = $this->setSql($sql . ' LIMIT ' . ($cpage - 1) * $size . ',' . $size)->fetchAll(); //获取当前页数据 //总页数 $ptotal = empty($total) ? 1 : ceil($total / $size); //下一页 $next = $cpage + 1; if ($next > $ptotal) { $next = $ptotal; } //上一页 $up = $cpage - 1; if ($up < 1) { $up = 1; } $page = ['param' => $param, 'size' => $size, 'page' => $cpage, 'last' => $ptotal, 'next' => $next, 'prev' => $up, 'total' => $total]; return ['page' => $page, 'data' => $data]; }
/** * 更新/恢复该版本下所有迁移模块 */ public function actAll() { $request = \H2O::getContainer('request'); //控制台请求 $params = $request->getParams(); if (empty($params['type'])) { echo 'Missing required parameter: type' . PHP_EOL; exit; } $mtype = 'act' . ucfirst($params['type']); //更新类型 up/restore $all = $this->_namespace . '\\All'; //全量数据列表 $oall = new $all(); if (!method_exists($oall, 'Regtable')) { echo $all . ' is not found method: regtable' . PHP_EOL; exit; } $regnames = $oall->Regtable(); //获取所有注册到全量的数据信息 if (empty($regnames) || !is_array($regnames)) { echo $all . ':regtable return value is empty or is not array!' . PHP_EOL; exit; } foreach ($regnames as $reg) { try { $class = $this->_namespace . '\\' . ucfirst($reg); $oc = new $class(); $oc->clearBuildSQL(); //清空上一个模块的SQL,防止重复写入 $oc->beginTransaction(); $oc->{$mtype}(); $oc->buildExec(); //执行SQL $oc->pdo->commit(); } catch (\Exception $e) { $oc->pdo->rollBack(); //回滚 throw new \ErrorException(PHP_EOL . 'Class name:' . $class . ',' . $e->getMessage()); } } echo 'Executed successfully!' . PHP_EOL; exit; }
/** * 启动 */ public function actStart() { $routep = $this->_getRoutePath(); //路由规则path $logfile = $this->_logpath . $routep . DS . date('Ymd') . '.log'; //记录日志信息 按天记录 $module = \H2O::getContainer('module'); $route = \H2O\base\Module::parseRoute($routep); //返回路由规则URL //启动时,要删除已产生的停止信号,防止启动时就退出 $this->_deleteSignal($routep); //写入进程信息 $pid = getmypid(); $pidfile = $this->_logpath . $routep . '.pid'; //进程存储文件 File::write($pidfile, $pid . ':' . date('Y-m-d H:i:s') . PHP_EOL); //写入存储信息 //循环业务处理 while (true) { $signal = $this->_getSignal($routep); //获取信号 if ($signal[0] == $this->_stopsignal) { //信号源为停止,并且是当前应用 //清理进程信息 if ($signal[1] == $pid) { $apid = file($pidfile); //读取所有进程信息 $apid = array_filter($apid); //过滤空格 $tmpid = []; foreach ($apid as $ap) { $ap = trim($ap); $opid = substr($ap, 0, strpos($ap, ':')); if ($opid != $pid && !empty($ap)) { $tmpid[] = $ap . PHP_EOL; } } if (empty($tmpid)) { //如果不存进程信息时,直接删除记录进程日志信息 File::remove($pidfile); //删除运行时的日志 } else { File::write($pidfile, implode('', $tmpid), false); //新写入进程日志 } } else { File::remove($pidfile); //删除运行时的日志 } exit; } else { $octr = $module->getController($route['controller']); //控制器对象 $gwmethod = 'Gate' . ucfirst($route['action']); //方法网关 if (method_exists($octr, $gwmethod)) { //增加入口应用关口,可在此函数中处理业务逻辑,可实现定时任务等 if ($octr->{$gwmethod}()) { //返回值只有为true时才执行相应的程序 $res = $octr->runAction(ucfirst($route['action'])); //执行操作 $content = 'pid:' . $pid . ' datetime:' . date('Y-m-d H:i:s') . ' response:' . $res . PHP_EOL; File::write($logfile, $content); //写入日志信息 } } else { $res = $octr->runAction(ucfirst($route['action'])); //执行操作 $content = 'pid:' . $pid . ' datetime:' . date('Y-m-d H:i:s') . ' response:' . $res . PHP_EOL; File::write($logfile, $content); //写入日志信息 } } sleep(1); //休眠时间 1秒 } }
/** * 返回请求信息 * @return 返回请求句柄 */ public function request() { return \H2O::getContainer('request'); }
/** * 守护子进程 */ public function actDaemon() { $routep = $this->_getRoutePath(); //路由规则path $module = \H2O::getContainer('module'); $route = \H2O\base\Module::parseRoute($routep); //返回路由规则URL $octr = $module->getController($route['controller']); //控制器对象 $gwmethod = 'Gate' . ucfirst($route['action']); //方法网关 $pid = getmypid(); //进程ID if (method_exists($octr, $gwmethod)) { //增加入口应用关口,可在此函数中处理业务逻辑,可实现定时任务等 $gwm = $octr->{$gwmethod}(); if ($gwm === true) { //返回值只有为true时才执行相应的程序 $res = $octr->runAction(ucfirst($route['action'])); //执行操作 $response = 'pid:' . $pid . ' datetime:' . date('Y-m-d H:i:s') . ' response:' . $res . PHP_EOL; } } else { $res = $octr->runAction(ucfirst($route['action'])); //执行操作 $response = 'pid:' . $pid . ' datetime:' . date('Y-m-d H:i:s') . ' response:' . $res . PHP_EOL; } echo $response; }
/** * 异常日志 * @param Exception $exception 异常信息 */ public function logException($exception) { $data = $this->parseException($exception); $logger = \H2O::getContainer('logger'); $env = \H2O::getRunEnv(); //获取运行环境 if ($env == 'prod') { //生产环境 $logger->exceptionWrite($data['message'], $data['files']); //写入错误日志 } else { //开发、测试环境 都直接显示错误 $logger->exceptionDebug($data['message'], $data['files']); //显示错误日志 方便调试 } if ($this->discardExistingOutput) { $this->clearOutput(); } }
/** * 返回模板渲染后的字符串 * @param string $tpl 模板文件 * @param array $vars 需要传入模板的数据参数 */ public function render($tpl, $vars = []) { $ov = \H2O::getContainer('view'); $ov->setFile($tpl); $ov->setController(new static()); //设置依附的控制器 $ov->setPath($this->getViewPath()); $ov->setContent($this->getContent()); $vars = array_merge(self::$viewglobalvars, $vars); //合并全局变量和局部变量 $content = $ov->render($vars); if (empty($this->_layout) || !empty($this->_content)) { //非布局 或者已有内容信息,则当前已为布局模块 return $content; } else { //有布局 $route = Module::parseRoute($this->_layout); $o = \H2O::createObject($this->_namespace . '\\' . $route['controller']); $o->setContent($content); //设置主模块缓存 return call_user_func([$o, 'act' . ucfirst($route['action'])]); } }