/** * 模板显示 调用内置的模板引擎显示方法, * * @param string $templateFile 指定要调用的模板文件 默认为空 由系统自动定位模板文件 * @param bool $inOtherApp 是否为载入其它应用的模板 * * @return void */ public function display($templateFile = '', $inOtherApp = false) { // 网页字符编码 header('Content-Type:text/html; charset=' . Config::get('default_charset')); echo $this->fetch($templateFile, $inOtherApp); Cml::cmlStop(); }
/** * 匹配路由 * * @param $pathinfo * * @return mixed */ public static function isRoute(&$pathinfo) { empty($pathinfo) && ($pathinfo[0] = '/'); //网站根地址 $issuccess = array(); $route = self::$rules; switch ($_SERVER['REQUEST_METHOD']) { case 'GET': $rmethod = self::REQUEST_METHOD_GET; break; case 'POST': $rmethod = self::REQUEST_METHOD_POST; break; case 'PUT': $rmethod = self::REQUEST_METHOD_PUT; break; case 'PATCH': $rmethod = self::REQUEST_METHOD_PATCH; break; case 'DELETE': $rmethod = self::REQUEST_METHOD_DELETE; break; case 'OPTIONS': $rmethod = self::REQUEST_METHOD_OPTIONS; break; default: $rmethod = self::REQUEST_METHOD_ANY; } foreach ($route as $k => $v) { $rulesmethod = substr($k, 0, 1); if ($rulesmethod != $rmethod && $rulesmethod != self::REQUEST_METHOD_ANY && $rulesmethod != self::RESTROUTE) { //此条路由不符合当前请求方式 continue; } unset($v); $singleRule = substr($k, 1); $arr = $singleRule === '/' ? array(0 => $singleRule) : explode('/', ltrim($singleRule, '/')); if ($arr[0] == $pathinfo[0]) { array_shift($arr); foreach ($arr as $key => $val) { if (isset($pathinfo[$key + 1]) && $pathinfo[$key + 1] !== '') { if (strpos($val, '\\d') && !is_numeric($pathinfo[$key + 1])) { //数字变量 $route[$k] = false; //匹配失败 break 1; } elseif (strpos($val, ':') === false && $val != $pathinfo[$key + 1]) { //字符串 $route[$k] = false; //匹配失败 break 1; } } else { $route[$k] = false; //匹配失败 break 1; } } } else { $route[$k] = false; //匹配失败 } if ($route[$k] !== false) { //匹配成功的路由 $issuccess[] = $k; } } if (empty($issuccess)) { $returnArr[0] = false; } else { //匹配到多条路由时 选择最长的一条(匹配更精确) usort($issuccess, function ($item1, $item2) { return strlen($item1) >= strlen($item2) ? 0 : 1; }); if (is_callable($route[$issuccess[0]])) { call_user_func($route[$issuccess[0]]); Cml::cmlStop(); } $route[$issuccess[0]] = trim($route[$issuccess[0]], '/'); //判断路由的正确性 count(explode('/', $route[$issuccess[0]])) >= 2 || throwException(Lang::get('_ROUTE_PARAM_ERROR_', substr($issuccess[0], 1))); $returnArr[0] = true; $successRoute = explode('/', $issuccess[0]); foreach ($successRoute as $key => $val) { $t = explode('\\d', $val); if (strpos($t[0], ':') !== false) { $_GET[ltrim($t[0], ':')] = $pathinfo[$key]; } unset($pathinfo[$key]); } if (substr($issuccess[0], 0, 1) == self::RESTROUTE) { $actions = explode('/', $route[$issuccess[0]]); $arrKey = count($actions) - 1; $actions[$arrKey] = strtolower($_SERVER['REQUEST_METHOD']) . ucfirst($actions[$arrKey]); $route[$issuccess[0]] = implode('/', $actions); } $returnArr['route'] = $route[$issuccess[0]]; } return $returnArr; }
/** * 解析url * * @return mixed */ public function parseUrl() { $dispatcher = \FastRoute\simpleDispatcher(function (RouteCollector $r) { foreach ($this->routes as $route) { $r->addRoute($route['method'], $route['uri'], $route['action']); } }); \Cml\Route::parsePathInfo(); $httpMethod = isset($_POST['_method']) ? strtoupper($_POST['_method']) : strtoupper($_SERVER['REQUEST_METHOD']); $routeInfo = $dispatcher->dispatch($httpMethod, implode('/', \Cml\Route::getPathInfo())); switch ($routeInfo[0]) { case Dispatcher::NOT_FOUND: case Dispatcher::METHOD_NOT_ALLOWED: break; case Dispatcher::FOUND: $_GET += $routeInfo[2]; if (is_callable($routeInfo[1])) { call_user_func($routeInfo[1]); Cml::cmlStop(); } $this->parseUrlParams($routeInfo[1]); break; } return $dispatcher; }
/** * 抽象display * * @param string $templateFile 模板文件 * * @return mixed */ public function display($templateFile = '') { $options = $this->initBaseDir($templateFile); $compiler = new BladeCompiler($options['cacheDir'], $options['layoutCacheRootPath']); $compiler->directive('datetime', function ($timestamp) { return preg_replace('/(\\(\\d+\\))/', '<?php echo date("Y-m-d H:i:s", $1); ?>', $timestamp); }); $compiler->directive('hook', function ($hook) { return preg_replace('/\\((.*?)\\)/', '<?php \\Cml\\Plugin::hook("$1"); ?>', $hook); }); $compiler->directive('urldeper', function () { return '<?php echo \\Cml\\Config::get("url_model") == 3 ? "&" : "?"; ?>'; }); $compiler->directive('get', function ($key) { return preg_replace('/\\((.*?)\\)/', '<?php echo \\Cml\\Http\\Input::getString("${1}");?>', $key); }); $compiler->directive('post', function ($key) { return preg_replace('/\\((.*?)\\)/', '<?php echo \\Cml\\Http\\Input::postString("${1}");?>', $key); }); $compiler->directive('request', function ($key) { return preg_replace('/\\((.*?)\\)/', '<?php echo \\Cml\\Http\\Input::requestString("${1}");?>', $key); }); $compiler->directive('url', function ($key) { return preg_replace('/\\((.*?)\\)/', '<?php echo \\Cml\\Http\\Response::url("${1}"); ?>', $key); }); $compiler->directive('public', function () { return '<?php echo \\Cml\\Config::get("static__path", \\Cml\\Cml::getContainer()->make("cml_route")->getSubDirName()."public/");?>'; }); $compiler->directive('token', function () { return '<input type="hidden" name="CML_TOKEN" value="<?php echo \\Cml\\Secure::getToken();?>" />'; }); $compiler->directive('lang', function ($lang) { return preg_replace('/\\((.*?)\\)/', '<?php echo \\Cml\\Lang::get("${1}"); ?>', $lang); }); $compiler->directive('config', function ($config) { return preg_replace('/\\((.*?)\\)/', '<?php echo \\Cml\\Config::get("${1}"); ?>', $config); }); $compiler->directive('assert', function ($url) { return preg_replace('/\\((.*?)\\)/', '<?php echo \\Cml\\Tools\\StaticResource::parseResourceUrl("${1}"); ?>', $url); }); $compiler->directive('acl', function ($url) { return preg_replace('/\\((.*?)\\)/', '<?php if (\\Cml\\Vendor\\Acl::checkAcl("${1}")) : ?>', $url); }); $compiler->directive('endacl', function () { return '<?php endif; ?>'; }); foreach ($this->rule as $pattern => $func) { $compiler->directive($pattern, $func); } $finder = new FileViewFinder([$options['templateDir'], $options['layoutDir']]); $finder->addExtension(trim(Config::get('html_template_suffix'), '.')); $factory = new Factory($compiler, $finder); header('Content-Type:text/html; charset=' . Config::get('default_charset')); echo $factory->make($options['file'], $this->args)->render(); Cml::cmlStop(); }