<?php
/**
* 模板引擎
*
*/
class View {
//编译目录
private $compile_dir = '/tmp/';
//存储文本数组
private $template_array;
//文件路径
private $file_name;
//include行号
private $INCLUDE;
//if开始标签行号
private $IF_START;
//else行号
private $IF_ELSE;
//if结束标签行号
private $IF_END;
//foreach开始标签行号
private $FOREACH_START;
//foreach结束标签行号
private $FOREACH_END;
public function __construct($file_name) {
$this->file_name = $file_name;
}
/**
* 模板编译
*/
public function complie() {
//将文件以数组的形式输出
$this->template_array = file($this->file_name);
//查找include
foreach ($this->template_array as $key => $value) {
$template_array[$key] = trim($value);
$mark = substr($template_array[$key], 0,8);
if ($mark == '{include')
$this->INCLUDE[] = $key;
}
//include存在则合并包含文件
if (isset($this->INCLUDE)) {
$this->pregInclude();
foreach ($this->template_array as $key => $value) {
if (is_array($value)) {
foreach ($value as $k => $v) {
$include_array[] = $v;
}
}
else {
$include_array[] = $value;
}
}
}
else {
$include_array = $this->template_array;
}
unset($this->template_array);
unset($template_array);
foreach ($include_array as $k => $v) {
$array[$k] = trim($v);
$mark = substr($array[$k], 0,4);
switch ($mark) {
//foreach开始
case '{for':$this->FOREACH_START[] = $k;
break;
//foreach结束
case '{/fo':$this->FOREACH_END[] = $k;
break;
//if开始
case '{if ':$this->IF_START[] = $k;
break;
//else
case '{els':$this->IF_ELSE[] = $k;
break;
//if结束
case '{/if':$this->IF_END[] = $k;
break;
}
}
$this->template_array = $include_array;
unset($include_array);
/**
* 转为php标签
*/
if (isset($this->FOREACH_START)) {
$this->pregForeachStart();
$this->pregEnd($this->FOREACH_END);
}
if (isset($this->IF_START)) {
$this->pregIfStart();
$this->pregEnd($this->IF_END);
}
if (isset($this->IF_ELSE)) {
$this->pregElse();
}
/**
* 写入文件
*/
$template_string = $this->pregString();
$complie_file = basename($this->file_name); //产生缟译后的文件名
$result = file_put_contents($this->compile_dir.'/view/'.$complie_file, $template_string);
if (is_int($result))
return $template_string;
else return false;
}
/**
* 合并include文件
* @param string $key :0
* @param string $value :{include file="/xx/xx.phtml"}
*/
private function pregInclude() {
foreach ($this->INCLUDE as $value) {
$tmp = explode("\"", $this->template_array[$value]);
$path = "/yby/site/YAE/application/views$tmp[1]";
if (!file_exists($path)) exit('文件不存在');
$this->template_array[$value] = file($path);
}
}
/**
* 替换foreach开始标签
* @param unknown $key
* @param unknown $value
*/
private function pregForeachStart() {
foreach ($this->FOREACH_START as $line) {
$value = $this->template_array[$line];
/**
* 分解foreach条件 "{foreach key=k value=data}"
* $foreach_condition[0] = "{foreach"
* $foreach_condition[1] = "key=k"
* $foreach_condition[2] = "data=$value}"
*/
$foreach_condition = explode(' ', trim($value));
$foreach_condition_data = rtrim($foreach_condition[2],'}');
/**
* $data = "data"
* $val = "$value"
*/
list($data,$val) = explode('=', $foreach_condition_data);
/**
* $key = "key"
* $k = "k"
*/
list($key,$k) = explode('=', $foreach_condition[1]);
$replace = "<?php foreach($val as $".$k." => $"."$data) {?>";
$this->template_array[$line] = $replace;
}
}
/**
* 替换if开始标签
* @param unknown $key
* @param unknown $value
*/
private function pregIfStart() {
//$line 行号
foreach ($this->IF_START as $line) {
$value = $this->template_array[$line];
/**
* $if_condition = "$data.status == 0" or "$value == null" or "isset($value)"
*/
$if_condition = substr(trim($value), 4);
$if_condition = rtrim($if_condition,'}');
$if_condition = explode(' ', $if_condition);
$count = count($if_condition);
switch ($count) {
case 1:
$replace = "<?php if(".$if_condition[0].") { ?>";
break;
case 2:
break;
case 3:
$if_condition_data = explode('.', $if_condition[0]);
$num = count($if_condition_data);
$data = $if_condition_data[0];
for ($i = 1; $i < $num; $i++) {
$data .= "['$if_condition_data[$i]']";
}
$replace = "<?php if(".$data.$if_condition[1].$if_condition[2].") { ?>";
break;
}
$this->template_array[$line] = $replace;
}
}
/**
* 替换结束标签
* @param unknown $key
*/
private function pregEnd($value) {
foreach ($value as $line) {
$replace = "<?php } ?>";
$this->template_array[$line] = $replace;
}
}
/**
* 替换else
* @param unknown $key
*/
private function pregElse() {
foreach ($this->IF_ELSE as $line) {
/**
* $if_condition[0] :"{else}" or "{elseif *** == ***}" or "{elseif isset(***)}"
*/
$if_condition = trim($this->template_array[$line]);
$if_condition = trim($if_condition,'{}');
$if_condition = explode(' ', $if_condition);
$count = count($if_condition);
switch ($count) {
case 1:
$replace = "<?php }else{ ?>";
break;
case 2:
$replace = "<?php }elseif($if_condition[1]) { ?>";
break;
case 4:
$if_condition_data = explode('.', $if_condition[1]);
$num = count($if_condition_data);
$data = $if_condition_data[0];
for ($i = 1; $i < $num; $i++) {
$data .= "['$if_condition_data[$i]']";
}
$replace = "<?php }elseif($data $if_condition[2] $if_condition[3]) { ?>";
break;
}
$this->template_array[$line] = $replace;
}
}
/**
* 直接输出字符串
*/
private function pregString() {
$template_string = implode('', $this->template_array);
/**
* $matches[0][$i] : "{$data.app_name}"
*/
preg_match_all("/\{(\\$(\b\w+\b\.)+\b\w+\b)\}|\{(\\$\b\w+\b)\}/", $template_string, $matches);
if (!empty($matches[0])) {
foreach ($matches[0] as $key => $val) {
$value = trim($val,'{}');
$data = explode('.', $value);
$count = count($data);
$result = $data[0];
for ($i = 1; $i < $count; $i++) {
$result .= "['$data[$i]']";
}
$replace = "<?php echo $result;?>";
$template_string = str_replace($val, $replace, $template_string);
}
}
return $template_string;
}
public function __destruct() {
unset($this->template_array);
}
}
转载于:https://my.oschina.net/voyage1314/blog/187224