swoole_framework /libs/system/View.php

Language PHP Lines 344
MD5 Hash 402c248fd08e8b060ac4b2ee9926a08d
Repository https://github.com/monkeycraps/swoole_framework.git View Raw File
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
<?php
/**
 * 视图类
 * 提供一个简单试图封装
 * @package SwooleSystem
 * @author Tianfeng.Han
 * @subpackage MVC
 */
class View extends ArrayObject
{
	protected $_var        =  array();
	protected $trace       = array();
	protected $swoole;
	public $template_dir = '';
	public $if_pagecache = false;
	public $cache_life = 3600;
	public $show_runtime = false;

	function __construct($swoole)
	{
		$this->swoole = $swoole;
		$this->template_dir = APPSPATH.'/views/';
	}

	/**
	 +----------------------------------------------------------
	 * 模板变量赋值
	 +----------------------------------------------------------
	 * @access public
	 +----------------------------------------------------------
	 * @param mixed $name
	 * @param mixed $value
	 +----------------------------------------------------------
	 */
	public function assign($name,$value='')
	{
		if(is_array($name))
		{
			$this->_var   =  array_merge($this->_var,$name);
		}elseif(is_object($name)){
			foreach($name as $key =>$val)
			{
				$this->_var[$key] = $val;
			}
		}else {
			$this->_var[$name] = $value;
		}
	}

	/**
	 +----------------------------------------------------------
	 * Trace变量赋值
	 +----------------------------------------------------------
	 * @access public
	 +----------------------------------------------------------
	 * @param mixed $name
	 * @param mixed $value
	 +----------------------------------------------------------
	 */
	public function trace($title,$value='') {
		if(is_array($title)) {
			$this->trace   =  array_merge($this->trace,$title);
		}else {
			$this->trace[$title] = $value;
		}
	}

	/**
	 +----------------------------------------------------------
	 * 取得模板变量的值
	 +----------------------------------------------------------
	 * @access public
	 +----------------------------------------------------------
	 * @param string $name
	 +----------------------------------------------------------
	 * @return mixed
	 +----------------------------------------------------------
	 */
	public function get($name){
		if(isset($this->_var[$name])) {
			return $this->_var[$name];
		}else {
			return false;
		}
	}

	/**
	 +----------------------------------------------------------
	 * 加载模板和页面输出 可以返回输出内容
	 +----------------------------------------------------------
	 * @access public
	 +----------------------------------------------------------
	 * @param string $templateFile 模板文件名 留空为自动获取
	 * @param string $charset 模板输出字符集
	 * @param string $contentType 输出类型
	 +----------------------------------------------------------
	 * @return mixed
	 +----------------------------------------------------------
	 */
	public function display($templateFile='',$charset='',$contentType='text/html')
	{
		$this->fetch($templateFile,$charset,$contentType,true);
	}

	/**
	 +----------------------------------------------------------
	 * 输出布局模板
	 +----------------------------------------------------------
	 * @access public
	 +----------------------------------------------------------
	 * @param string $charset 输出编码
	 * @param string $contentType 输出类型
	 * @param string $display 是否直接显示
	 +----------------------------------------------------------
	 * @return mixed
	 +----------------------------------------------------------
	 */
	public function layout($content,$charset='',$contentType='text/html')
	{
		// 查找布局包含的页面
		$find = preg_match_all('/<!-- layout::(.+?)::(.+?) -->/is',$content,$matches);
		if($find) {
			for ($i=0; $i< $find; $i++) {
				// 读取相关的页面模板替换布局单元
				if(0===strpos($matches[1][$i],'$')){
					// 动态布局
					$matches[1][$i]  =  $this->get(substr($matches[1][$i],1));
				}
				if(0 != $matches[2][$i] ) {
					// 设置了布局缓存
					// 检查布局缓存是否有效
					$guid =  md5($matches[1][$i]);
					$cache  =  S($guid);
					if($cache) {
						$layoutContent = $cache;
					}else{
						$layoutContent = $this->fetch($matches[1][$i],$charset,$contentType);
						S($guid,$layoutContent,$matches[2][$i]);
					}
				}else{
					$layoutContent = $this->fetch($matches[1][$i],$charset,$contentType);
				}
				$content    =   str_replace($matches[0][$i],$layoutContent,$content);
			}
		}
		return $content;
	}

	/**
	 +----------------------------------------------------------
	 * 加载模板和页面输出
	 +----------------------------------------------------------
	 * @access public
	 +----------------------------------------------------------
	 * @param string $templateFile 模板文件名 留空为自动获取
	 * @param string $charset 模板输出字符集
	 * @param string $contentType 输出类型
	 * @param string $display 是否直接显示
	 +----------------------------------------------------------
	 * @return mixed
	 +----------------------------------------------------------
	 */
	public function fetch($templateFile='',$charset='',$contentType='text/html',$display=false)
	{
		$GLOBALS['_viewStartTime'] = microtime(TRUE);
		if(null===$templateFile) {
			// 使用null参数作为模版名直接返回不做任何输出
			return ;
		}
		if(empty($charset)) {
			$charset = 'utf-8';
		}
		// 网页字符编码
		header("Content-Type:".$contentType."; charset=".$charset);
		header("Cache-control: private");  //支持页面回跳
		//页面缓存
		ob_start();
		ob_implicit_flush(0);
		$this->render($templateFile);
		// 获取并清空缓存
		$content = ob_get_clean();

		// 布局模板解析
		$content = $this->layout($content,$charset,$contentType);
		// 输出模板文件
		return $this->output($content,$display);
	}
	
	private function render($templateFile)
	{
		extract($this->_var);
		$templateFile = $this->parseTemplateFile($templateFile);
		require($templateFile);	
	}

	/**
	 +----------------------------------------------------------
	 *  创建静态页面
	 +----------------------------------------------------------
	 * @access public
	 +----------------------------------------------------------
	 * @htmlfile 生成的静态文件名称
	 * @param string $templateFile 指定要调用的模板文件
	 * 默认为空 由系统自动定位模板文件
	 * @param string $charset 输出编码
	 * @param string $contentType 输出类型
	 +----------------------------------------------------------
	 * @return string
	 +----------------------------------------------------------
	 */
	public function buildHtml($htmlfile='',$templateFile='',$charset='',$contentType='text/html') {
		$content = $this->fetch($templateFile,$charset,$contentType);
		if(empty($htmlfile)) {
			$htmlfile =  HTML_PATH.rtrim($_SERVER['PATH_INFO'],'/').C('HTML_FILE_SUFFIX');
		}
		if(!is_dir(dirname($htmlfile))) {
			// 如果静态目录不存在 则创建
			mk_dir(dirname($htmlfile));
		}
		if(false === file_put_contents($htmlfile,$content)){
			throw_exception(L('_CACHE_WRITE_ERROR_'));
		}
		return $content;//readfile($htmlfile);
	}

	/**
	 +----------------------------------------------------------
	 * 输出模板
	 +----------------------------------------------------------
	 * @access protected
	 +----------------------------------------------------------
	 * @param string $content 模板内容
	 * @param boolean $display 是否直接显示
	 +----------------------------------------------------------
	 * @return mixed
	 +----------------------------------------------------------
	 */
	protected function output($content,$display) {
		if($this->if_pagecache)
		{
			$pagecache = new Swoole_pageCache($this->cache_life);
			if($pagecache->isCached()) $pagecache->load();
			else $pagecache->create($content);
		}
		if($display)
		{
			$showTime = $this->showTime();
			echo $content;
			if($this->show_runtime) $this->showTrace();
			return null;
		}
		else return $content;
	}

	private function parseTemplateFile($templateFile)
	{
		if(''==$templateFile)
		{
			$templateFile = $this->swoole->env['mvc']['controller'].'_'.$this->swoole->env['mvc']['view'].'.html';
		}
		$templateFile = $this->template_dir.$templateFile;
		if(!file_exists($templateFile))
		{
			Error::info('View Error!','Template file not exists! <b>'.$templateFile.'</b>');
		}
		return $templateFile;
	}

	/**
	 +----------------------------------------------------------
	 * 显示运行时间、数据库操作、缓存次数、内存使用信息
	 +----------------------------------------------------------
	 * @access protected
	 +----------------------------------------------------------
	 * @return string
	 +----------------------------------------------------------
	 */
	protected function showTime()
	{
		// 显示运行时间
		$startTime =  $this->swoole->env['runtime']['start'];
		$endTime = microtime(TRUE);
		$total_run_time =   number_format(($endTime - $startTime),4);
		$showTime = '执行时间: '.$total_run_time.'s ';
		
		$startMem    =  array_sum(explode(' ',$this->swoole->env['runtime']['mem']));
		$endMem     =  array_sum(explode(' ', memory_get_usage()));
		$showTime .= ' | 内存占用:'. number_format(($endMem - $startMem)/1024).' kb';
		return $showTime;
	}

	/**
	 +----------------------------------------------------------
	 * 显示页面Trace信息
	 +----------------------------------------------------------
	 * @access protected
	 +----------------------------------------------------------
	 * @param string $showTime 运行时间信息
	 +----------------------------------------------------------
	 */
	public function showTrace($detail=false)
	{
		// 显示页面Trace信息 读取Trace定义文件
		// 定义格式 return array('当前页面'=>$_SERVER['PHP_SELF'],'通信协议'=>$_SERVER['SERVER_PROTOCOL'],...);
		$_trace =   array();
		// 系统默认显示信息
		$this->trace('当前页面',    $_SERVER['REQUEST_URI']);
		$this->trace('请求方法',    $_SERVER['REQUEST_METHOD']);
		$this->trace('通信协议',    $_SERVER['SERVER_PROTOCOL']);
		$this->trace('请求时间',    date('Y-m-d H:i:s',$_SERVER['REQUEST_TIME']));
		$this->trace('用户代理',    $_SERVER['HTTP_USER_AGENT']);
		if(isset($_SESSION)) $this->trace('会话ID'   ,   session_id());
		$this->trace('读取数据库',   $this->swoole->db->read_times.'次');
		$this->trace('写入数据库',   $this->swoole->db->write_times.'次');
		$included_files = get_included_files();
		$this->trace('加载文件',     count($included_files));
		$this->trace('PHP执行',      $this->showTime());
		$_trace =   array_merge($_trace,$this->trace);
		// 调用Trace页面模板
		echo <<<HTML
		<div id="think_page_trace" style="background:white;margin:6px;font-size:14px;border:1px dashed silver;padding:8px">
		<fieldset id="querybox" style="margin:5px;">
		<legend style="color:gray;font-weight:bold">页面Trace信息</legend>
		<div style="overflow:auto;height:300px;text-align:left;">
HTML;
		 
		foreach ($_trace as $key=>$info)
		{
			echo $key.' : '.$info.'<br/>';
		}
		if($detail)
		{
			//输出包含的文件
			echo '加载的文件<br/>';
			foreach ($included_files as $file)
			{
				echo 'require '.$file.'<br/>';
			}
		}
		echo "</div></fieldset>	</div>";
	}
}
?>
Back to Top