够用的PHP模板引擎 'text/html', 'html' = 'text/html', 'css' = 'text/css', 'txt' = 'text/plain', 'xml' = 'text/xml', 'gif' = 'image/gif', 'jpeg' = 'image/jpeg', 'jpg' = 'image/jpeg', 'png' = 'image/png', 'js' = 'application/javascript'
'text/html', 'html' => 'text/html', 'css' => 'text/css', 'txt' => 'text/plain', 'xml' => 'text/xml', 'gif' => 'image/gif', 'jpeg' => 'image/jpeg', 'jpg' => 'image/jpeg', 'png' => 'image/png', 'js' => 'application/javascript', 'json' => 'application/json', 'bin' => 'application/octet-stream', ]; public $globals = []; public $charset = ''; protected $frame_files = []; protected $stack = []; protected $blocks = []; /** * 构造函数. */ public function __construct(array $config = []) { if (isset($config['globals']) && is_array($config['globals'])) { $this->addGlobal($config['globals']); } } /** * 添加一个或多个全局变量. * * @param string|array $key 一个变量名或变量数组 * @param mixed $value 变量值 * @return this */ public function addGlobal($key, $value = null) { if (is_array($key)) { $this->globals = array_replace($this->globals, $key); } else { $this->globals[$key] = $value; } return $this; } /** * 发送HTTP错误. */ public static function abort($code = 500) { $code = is_numeric($code) ? intval($code) : 500; http_response_code($code); if ($code >= 400) { return sprintf('%s
', 'An Error Was Encountered'); } } /** * 页面跳转,GET方式. * * @param string $to_url 要跳转网址 * @param bool $permanent 是否永久跳转(HTTP 301) * * @return 进入新页面 */ public static function redirect($to_url = '', $permanent = false) { $status_code = $permanent ? 301 : 302; self::header('Location', $to_url, true, $status_code); return die(); //阻止运行后面的代码 } /** * 发送Header. */ public static function header($name, $value, $replace = true, $code = 200) { if (!headers_sent()) { $line = empty($name) ? '' : strval($name) . ': '; $line .= is_array($value) ? implode(' ', $value) : strval($value); @header($line, $replace, $code); } } /** * 添加模板文件. * * @param string $frame_file 模板文件 * @return this */ public function addFrameFile($frame_file) { if ($frame_file && is_readable($frame_file)) { $this->frame_files[] = $frame_file; } return $this; } /** * 设置布局文件. * * @param string $layout_file 布局文件 * @return this */ public function extendTpl($layout_file) { if ($layout_file && is_readable($layout_file)) { array_unshift($this->frame_files, $layout_file); } return $this; } /** * 包含模板文件. * * @param string $frame_file 模板文件 */ public function includeTpl($frame_file) { if ($frame_file && is_readable($frame_file)) { extract($this->globals); include $frame_file; } } /** * 标示区块开始. * * @param string $name 区块名称 */ public function blockStart($name = 'content') { array_push($this->stack, $name); ob_start(); } /** * 标示区块结束 */ public function blockEnd() { $block_html = trim(ob_get_clean()); if ($name = array_pop($this->stack)) { $this->blocks[$name] = $block_html; } } /** * 返回区块内容. * * @param string $name 区块名称 */ public function block($name = 'content') { if (isset($this->blocks[$name])) { return $this->blocks[$name]; } } /** * 设置文档类型和字符集 * * @param string $type 文档类型 * @param string $charset 字符集 * @return this */ public function setContentType($type, $charset = 'utf-8') { $line = self::$mime_types[$type]; if ($charset) { $this->charset = strval($charset); $line .= '; charset=' . $this->charset; } self::header('Content-Type', $line); return $this; } /** * 获取输出内容. * * @param array $context 模板变量数组 * @return string */ public function render(array $context = []) { extract($this->globals); extract($context); ob_start(); //frame_files数组在动态增长,不能使用for循环 while (count($this->frame_files)) { $frame_file = array_pop($this->frame_files); include $frame_file; } return trim(ob_get_clean()); } }