View.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. namespace think;
  12. class View
  13. {
  14. // 视图实例
  15. protected static $instance;
  16. // 模板引擎实例
  17. /**
  18. * @var Template
  19. */
  20. public $engine;
  21. // 模板变量
  22. protected $data = [];
  23. // 用于静态赋值的模板变量
  24. protected static $var = [];
  25. // 视图输出替换
  26. protected $replace = [];
  27. /**
  28. * 构造函数
  29. * @access public
  30. * @param array $engine 模板引擎参数
  31. * @param array $replace 字符串替换参数
  32. */
  33. public function __construct($engine = [], $replace = [])
  34. {
  35. // 初始化模板引擎
  36. $this->engine($engine);
  37. // 基础替换字符串
  38. $request = Request::instance();
  39. $base = $request->root();
  40. $root = strpos($base, '.') ? ltrim(dirname($base), DS) : $base;
  41. if ('' != $root) {
  42. $root = '/' . ltrim($root, '/');
  43. }
  44. $baseReplace = [
  45. '__ROOT__' => $root,
  46. '__URL__' => $base . '/' . $request->module() . '/' . Loader::parseName($request->controller()),
  47. '__STATIC__' => $root . '/static',
  48. '__CSS__' => $root . '/static/css',
  49. '__JS__' => $root . '/static/js',
  50. ];
  51. $this->replace = array_merge($baseReplace, (array) $replace);
  52. }
  53. /**
  54. * 初始化视图
  55. * @access public
  56. * @param array $engine 模板引擎参数
  57. * @param array $replace 字符串替换参数
  58. * @return object
  59. */
  60. public static function instance($engine = [], $replace = [])
  61. {
  62. if (is_null(self::$instance)) {
  63. self::$instance = new self($engine, $replace);
  64. }
  65. return self::$instance;
  66. }
  67. /**
  68. * 模板变量静态赋值
  69. * @access public
  70. * @param mixed $name 变量名
  71. * @param mixed $value 变量值
  72. * @return void
  73. */
  74. public static function share($name, $value = '')
  75. {
  76. if (is_array($name)) {
  77. self::$var = array_merge(self::$var, $name);
  78. } else {
  79. self::$var[$name] = $value;
  80. }
  81. }
  82. /**
  83. * 模板变量赋值
  84. * @access public
  85. * @param mixed $name 变量名
  86. * @param mixed $value 变量值
  87. * @return $this
  88. */
  89. public function assign($name, $value = '')
  90. {
  91. if (is_array($name)) {
  92. $this->data = array_merge($this->data, $name);
  93. } else {
  94. $this->data[$name] = $value;
  95. }
  96. return $this;
  97. }
  98. /**
  99. * 设置当前模板解析的引擎
  100. * @access public
  101. * @param array|string $options 引擎参数
  102. * @return $this
  103. */
  104. public function engine($options = [])
  105. {
  106. if (is_string($options)) {
  107. $type = $options;
  108. $options = [];
  109. } else {
  110. $type = !empty($options['type']) ? $options['type'] : 'Think';
  111. }
  112. $class = false !== strpos($type, '\\') ? $type : '\\think\\view\\driver\\' . ucfirst($type);
  113. if (isset($options['type'])) {
  114. unset($options['type']);
  115. }
  116. $this->engine = new $class($options);
  117. return $this;
  118. }
  119. /**
  120. * 配置模板引擎
  121. * @access private
  122. * @param string|array $name 参数名
  123. * @param mixed $value 参数值
  124. * @return $this
  125. */
  126. public function config($name, $value = null)
  127. {
  128. $this->engine->config($name, $value);
  129. return $this;
  130. }
  131. /**
  132. * 解析和获取模板内容 用于输出
  133. * @param string $template 模板文件名或者内容
  134. * @param array $vars 模板输出变量
  135. * @param array $replace 替换内容
  136. * @param array $config 模板参数
  137. * @param bool $renderContent 是否渲染内容
  138. * @return string
  139. * @throws Exception
  140. */
  141. public function fetch($template = '', $vars = [], $replace = [], $config = [], $renderContent = false)
  142. {
  143. // 模板变量
  144. $vars = array_merge(self::$var, $this->data, $vars);
  145. // 页面缓存
  146. ob_start();
  147. ob_implicit_flush(0);
  148. // 渲染输出
  149. try {
  150. $method = $renderContent ? 'display' : 'fetch';
  151. // 允许用户自定义模板的字符串替换
  152. $replace = array_merge($this->replace, $replace, $this->engine->config('tpl_replace_string'));
  153. $this->engine->config('tpl_replace_string', $replace);
  154. $this->engine->$method($template, $vars, $config);
  155. } catch (\Exception $e) {
  156. ob_end_clean();
  157. throw $e;
  158. }
  159. // 获取并清空缓存
  160. $content = ob_get_clean();
  161. // 内容过滤标签
  162. Hook::listen('view_filter', $content);
  163. return $content;
  164. }
  165. /**
  166. * 视图内容替换
  167. * @access public
  168. * @param string|array $content 被替换内容(支持批量替换)
  169. * @param string $replace 替换内容
  170. * @return $this
  171. */
  172. public function replace($content, $replace = '')
  173. {
  174. if (is_array($content)) {
  175. $this->replace = array_merge($this->replace, $content);
  176. } else {
  177. $this->replace[$content] = $replace;
  178. }
  179. return $this;
  180. }
  181. /**
  182. * 渲染内容输出
  183. * @access public
  184. * @param string $content 内容
  185. * @param array $vars 模板输出变量
  186. * @param array $replace 替换内容
  187. * @param array $config 模板参数
  188. * @return mixed
  189. */
  190. public function display($content, $vars = [], $replace = [], $config = [])
  191. {
  192. return $this->fetch($content, $vars, $replace, $config, true);
  193. }
  194. /**
  195. * 模板变量赋值
  196. * @access public
  197. * @param string $name 变量名
  198. * @param mixed $value 变量值
  199. */
  200. public function __set($name, $value)
  201. {
  202. $this->data[$name] = $value;
  203. }
  204. /**
  205. * 取得模板显示变量的值
  206. * @access protected
  207. * @param string $name 模板变量
  208. * @return mixed
  209. */
  210. public function __get($name)
  211. {
  212. return $this->data[$name];
  213. }
  214. /**
  215. * 检测模板变量是否设置
  216. * @access public
  217. * @param string $name 模板变量名
  218. * @return bool
  219. */
  220. public function __isset($name)
  221. {
  222. return isset($this->data[$name]);
  223. }
  224. }