心理咨询网
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <?php
  2. /**
  3. * @copyright (C)2016-2099 Hnaoyun Inc.
  4. * @author XingMeng
  5. * @email hnxsh@foxmail.com
  6. * @date 2016年11月6日
  7. * 模板显示类
  8. */
  9. namespace core\view;
  10. use core\basic\Config;
  11. class View
  12. {
  13. // 模板路径
  14. protected $tplPath;
  15. // 编译路径
  16. protected $tplcPath;
  17. // 缓存路径
  18. protected $cachePath;
  19. // 存储注入变量
  20. protected $vars = array();
  21. // 存储包含文件
  22. protected $incFile = array();
  23. // 实例
  24. protected static $view;
  25. // 获取单一实例
  26. public static function getInstance()
  27. {
  28. if (! self::$view) {
  29. self::$view = new self();
  30. }
  31. return self::$view;
  32. }
  33. // 禁止通过new实例化类
  34. private function __construct()
  35. {
  36. $this->tplPath = APP_VIEW_PATH;
  37. $this->tplcPath = RUN_PATH . '/complile';
  38. $this->cachePath = RUN_PATH . '/cache';
  39. check_dir($this->tplcPath, true);
  40. check_dir($this->cachePath, true);
  41. }
  42. private function __clone()
  43. {
  44. die('不允许克隆对象!请使用getInstance获取实例');
  45. }
  46. // 变量注入
  47. public function assign($var, $value)
  48. {
  49. if (! empty($var)) {
  50. if (isset($this->vars[$var])) {
  51. error('模板变量$' . $var . '出现重复注入!');
  52. }
  53. $this->vars[$var] = $value;
  54. return true;
  55. } else {
  56. error('传递的设置模板变量有误');
  57. }
  58. }
  59. // 变量获取
  60. public function getVar($var)
  61. {
  62. if (! empty($var)) {
  63. if (isset($this->vars[$var])) {
  64. return $this->vars[$var];
  65. } else {
  66. return null;
  67. }
  68. } else {
  69. error('传递的获取模板变量有误');
  70. }
  71. }
  72. // 解析模板文件
  73. public function parser($file)
  74. {
  75. // 设置主题
  76. $theme = isset($this->vars['theme']) ? $this->vars['theme'] : 'default';
  77. $theme = preg_replace_r('{\.\.(\/|\\\\)}', '', $theme); // 过滤掉相对路径
  78. $file = preg_replace_r('{\.\.(\/|\\\\)}', '', $file); // 过滤掉相对路径
  79. if (strpos($file, '/') === 0) { // 绝对路径模板
  80. $tpl_file = ROOT_PATH . $file;
  81. } elseif (! ! $pos = strpos($file, '@')) { // 跨模块调用
  82. $path = APP_PATH . '/' . substr($file, 0, $pos) . '/view/' . $theme;
  83. define('APP_THEME_DIR', str_replace(DOC_PATH, '', $path));
  84. if (! is_dir($path)) { // 检查主题是否存在
  85. error('模板主题目录不存在!主题路径:' . $path);
  86. } else {
  87. $this->tplPath = $path;
  88. }
  89. $tpl_file = $path . '/' . substr($file, $pos + 1);
  90. } else {
  91. // 定义当前应用主题目录
  92. define('APP_THEME_DIR', str_replace(DOC_PATH, '', APP_VIEW_PATH) . '/' . $theme);
  93. if (! is_dir($this->tplPath .= '/' . $theme)) { // 检查主题是否存在
  94. error('模板主题目录不存在!主题路径:' . APP_THEME_DIR);
  95. }
  96. $tpl_file = $this->tplPath . '/' . $file; // 模板文件
  97. }
  98. $note = Config::get('tpl_html_dir') ? '<br>同时检测到您后台配置中配置了模板子目录,请核对是否是此原因导致!' : '';
  99. file_exists($tpl_file) ?: error('模板文件' . basename($file) . '不存在!' . $note);
  100. $tpl_c_file = $this->tplcPath . '/' . md5($tpl_file) . '.php'; // 编译文件
  101. // 当编译文件不存在,或者模板文件修改过,则重新生成编译文件
  102. if (! file_exists($tpl_c_file) || filemtime($tpl_c_file) < filemtime($tpl_file) || ! Config::get('tpl_parser_cache')) {
  103. $content = Parser::compile($this->tplPath, $tpl_file); // 解析模板
  104. file_put_contents($tpl_c_file, $content) ?: error('编译文件' . $tpl_c_file . '生成出错!请检查目录是否有可写权限!'); // 写入编译文件
  105. $compile = true;
  106. }
  107. ob_start(); // 开启缓冲区,引入编译文件
  108. $rs = include $tpl_c_file;
  109. if (! isset($compile)) {
  110. foreach ($rs as $value) { // 检查包含文件是否更新,其中一个包含文件不存在或修改则重新解析模板
  111. if (! file_exists($value) || filemtime($tpl_c_file) < filemtime($value) || ! Config::get('tpl_parser_cache')) {
  112. $content = Parser::compile($this->tplPath, $tpl_file); // 解析模板
  113. file_put_contents($tpl_c_file, $content) ?: error('编译文件' . $tpl_c_file . '生成出错!请检查目录是否有可写权限!'); // 写入编译文件
  114. ob_clean();
  115. include $tpl_c_file;
  116. break;
  117. }
  118. }
  119. }
  120. $content = ob_get_contents();
  121. ob_end_clean();
  122. return $content;
  123. }
  124. // 缓存页面, 开启缓存开关时有效
  125. public function cache($content)
  126. {
  127. if (Config::get('tpl_html_cache') && ! query_string('p,s')) {
  128. $lg = cookie('lg');
  129. if (Config::get('open_wap') && (is_mobile() || Config::get('wap_domain') == get_http_host())) {
  130. $wap = 'wap';
  131. } else {
  132. $wap = '';
  133. }
  134. $cacheFile = $this->cachePath . '/' . md5(get_http_url() . $_SERVER["REQUEST_URI"] . $lg . $wap) . '.html'; // 缓存文件
  135. file_put_contents($cacheFile, $content) ?: error('缓存文件' . $cacheFile . '生成出错!请检查目录是否有可写权限!'); // 写入缓存文件
  136. return true;
  137. }
  138. return false;
  139. }
  140. }