<?php /* * PHPlib模板7.4中文版(不足之处还请各位指正) * (C) Copyright 1999-2000 NetUSE GmbH * Kristian Koehntopp * 彭赞群注释于2004年6月,QQ:9537075 TEL:13787877670 * Email:mylovepzq@163.com */
/*这里是定义类Template*/ class Template { /* 如果设置了,则输出参数 */ var $classname = "Template"; var $debug = false; //是否调试
var $root = "."; //root为模板文件的存放目录
var $file = array(); //包含了所有的模板文件名和模板名的数组
var $varkeys = array(); //存放文本元素的键名
var $varvals = array(); //存放文本元素的值
var $unknowns = "remove"; /* "remove" => 删除未定义的变量 "comment" => 将未定义的变量变成注释 "keep" => 保留未定义的变量 */ var $halt_on_error = "yes"; /* "yes" => 退出 "report" => 报告错误,继续运行* "no" => 忽略错误*/ var $last_error = ""; /* 上一次的错误保存在这里 */ /* public: 构造函数 * root: 模板目录 * unknowns: 如何处理未知的变量(译者:变量定义为{ name }) */
/*这里是定义函数Template*/ function Template($root = ".", $unknowns = "remove") { if ($this->debug & 4) { echo"模板: root = $root, unknowns = $unknowns \n"; } $this->set_root($root); //默认将文件目录设置为相同的目录
$this->set_unknowns($unknowns); //unknowns默认设置为"remove"
}
/*这里是函数set_root*/ function set_root($root) { if ($this->debug & 4) { echo"设置根目录: root = $root \n"; } if (!is_dir($root)) { $this->halt("设置根目录: $root 不是一个无效的目录."); return false; } $this->root = $root; return true; }
//这里是函数set_unknowns,即对未知变量的处理
function set_unknowns($unknowns = "remove") { if ($this->debug & 4) { echo"未知的: 未知 = $unknowns \n"; } $this->unknowns = $unknowns; }
/*这里是函数set_file.......................................................*/ //该方法在数组file中根据$varname提供的键名加入值
function set_file($varname, $filename = "") { if (!is_array($varname)) //如果varname是数组
{ if ($this->debug & 4) { echo "设置文件: (with scalar) varname = $varname, filename = $filename \n"; } if ($filename == "") //如果文件名为空,输出错误
{ $this->halt("设置文件:变量名 $varname 文件名是空的."); return false; } $this->file[$varname] = $this->filename($filename); } else { reset($varname); //将varname的键名作为file数组的键名
//将键名对应的值作为file数组的值
while (list($v, $f) = each($varname)) { if ($this->debug & 4) { echo "set_file: (with array) varname = $v, filename = $f \n"; } if ($f == "") { $this->halt("set_file: For varname $v filename is empty."); return false; } $this->file[$v] = $this->filename($f); } } return true; }
//该方法取出某个父模板文件中的一个子模板
//将其作为块来加载
//并用另外一个模板变量取代之
/* public: set_file(array $filelist) * comment: 设置多个模板文件 * filelist: (句柄,文件名)数组 * public: set_file(string $handle, string $filename) * comment: 设置一个模板文件 * handle: 文件的句柄 * filename: 模板文件名 */ function set_block($parent, $varname, $name = "") { if ($this->debug & 4) { echo "set_block: parent = $parent, varname = $varname, name = $name \n"; } if (!$this->loadfile($parent)) { $this->halt("set_block: unable to load $parent."); return false; } if ($name == "") { $name = $varname; //如果没有指定模板变量的值就用子模板名作为模板变量名
}
$str = $this->get_var($parent); $reg = "/[ \t]*\s*?\n?(\s*.*?\n?)\s*\s*?\n?/sm"; preg_match_all($reg, $str, $m); $str = preg_replace($reg, "{ "."$name }", $str); $this->set_var($varname, $m[1][0]); $this->set_var($parent, $str); return true; }
//该方法向Varname和varkeys数组中添加新的键一值对
/* public: set_var(array $values) * values: (变量名,值)数组 * public: set_var(string $varname, string $value) * varname: 将被定义的变量名 * value: 变量的值 */ function set_var($varname, $value = "", $append = false) { if (!is_array($varname)) //如果不是阵列
{ if (!empty($varname)) //如果是空的
{ if ($this->debug & 1) { printf("set_var: (with scalar) %s = '%s' \n", $varname, htmlentities($value)); } $this->varkeys[$varname] = "/".$this->varname($varname)."/"; if ($append && isset($this->varvals[$varname])) { $this->varvals[$varname] .= $value; } else { $this->varvals[$varname] = $value; } } } else { reset($varname); while (list($k, $v) = each($varname)) { if (!empty($k)) { if ($this->debug & 1) { printf("set_var: (with array) %s = '%s' \n", $k, htmlentities($v)); } $this->varkeys[$k] = "/".$this->varname($k)."/"; if ($append && isset($this->varvals[$k])) { $this->varvals[$k] .= $v; } else { $this->varvals[$k] = $v; } } } } }
//定义函数clear_var
function clear_var($varname) { if (!is_array($varname)) //如果varname不是阵列
{ if (!empty($varname)) //如果是空的
{ if ($this->debug & 1) { printf("clear_var: (with scalar) %s \n", $varname); } $this->set_var($varname, ""); } } else { reset($varname); while (list($k, $v) = each($varname)) { if (!empty($v)) { if ($this->debug & 1) { printf("clear_var: (with array) %s \n", $v); } $this->set_var($v, ""); } } } }
/*这里是函数unset_var,删除变量的定义*/ function unset_var($varname) { if (!is_array($varname)) { if (!empty($varname)) { if ($this->debug & 1) { printf("unset_var: (with scalar) %s \n", $varname); } unset($this->varkeys[$varname]); unset($this->varvals[$varname]); } } else { reset($varname); while (list($k, $v) = each($varname)) { if (!empty($v)) { if ($this->debug & 1) { printf("unset_var: (with array) %s \n", $v); } unset($this->varkeys[$v]); unset($this->varvals[$v]); } } } }
//将模板文件中的变化内容替换成确定内容的操作,实现数据和显示的分离
function subst($varname) { $varvals_quoted = array(); if ($this->debug & 4) { echo"subst: varname = $varname \n"; } if (!$this->loadfile($varname)) //装载模板文件,如果出错就停止
{ $this->halt("subst: unable to load $varname."); return false; }
reset($this->varvals); while (list($k, $v) = each($this->varvals)) { $varvals_quoted[$k] = preg_replace(array('/\\\\/', '/\$/'), array ('\\\\\\', '\\\\$'), $v); }
//读入文件内容到字符串中并在下行对已知键值进行替换并返回结果
$str = $this->get_var($varname); $str = preg_replace($this->varkeys, $varvals_quoted, $str); return $str; }
//同subst,只是直接输出结果
function psubst($varname) { if ($this->debug & 4) { echo"psubst: varname = $varname \n"; } print $this->subst($varname);
return false; }
//将varname代表的一个或多个文件中的内容完成替换
//存放在target为键值的varvals数组无素中或追加到其后
//返回值和sub相同
function parse($target, $varname, $append = false) { if (!is_array($varname)) { if ($this->debug & 4) { echo "parse: (with scalar) target = $target, varname = $varname, append = $append \n"; } $str = $this->subst($varname); if ($append) { $this->set_var($target, $this->get_var($target).$str); } else { $this->set_var($target, $str); } } else { reset($varname); while (list($i, $v) = each($varname)) { if ($this->debug & 4) { echo "parse: (with array) target = $target, i = $i, varname = $v, append = $append \n"; } $str = $this->subst($v); if ($append) { $this->set_var($target, $this->get_var($target).$str); } else { $this->set_var($target, $str); } } }
if ($this->debug & 4) { echo"parse: completed \n"; } return $str; }
//同parse方法,只是该方法将结果输出
function pparse($target, $varname, $append = false) { if ($this->debug & 4) { echo"pparse: passing parameters to parse... \n"; } print $this->finish($this->parse($target, $varname, $append)); return false; }
//返回所有的键一值对中的值所组成的数组
function get_vars() { if ($this->debug & 4) { echo"get_vars: constructing array of vars... \n"; } reset($this->varkeys); while (list($k, $v) = each($this->varkeys)) { $result[$k] = $this->get_var($k); } return $result; }
//根据键名返回对应的键一值勤对应的值
function get_var($varname) { if (!is_array($varname)) //如果不是阵列
{ if (isset($this->varvals[$varname])) //如果变量不存在
{ $str = $this->varvals[$varname]; } else { $str = ""; } if ($this->debug & 2) { printf("get_var (with scalar) %s = '%s' \n", $varname, htmlentities($str)); } return $str; } else { reset($varname); while (list($k, $v) = each($varname)) { if (isset($this->varvals[$v])) { $str = $this->varvals[$v]; } else { $str = ""; } if ($this->debug & 2) { printf("get_var: (with array) %s = '%s' \n", $v, htmlentities($str)); } $result[$v] = $str; } return $result; } }
//如果加载文件失败,返回错误并停止
function get_undefined($varname) { if ($this->debug & 4) { echo"get_undefined: varname = $varname \n"; } if (!$this->loadfile($varname)) { $this->halt("get_undefined: unable to load $varname."); return false; }
preg_match_all("/{ ([^ \t\r\n }]+) }/", $this->get_var($varname), $m); $m = $m[1]; //如果无法找到匹配的文本,返回错误
if (!is_array($m)) { return false; } //如果能找到大括号中的非空字符,则将其值作为键值,组成一个新的数组
reset($m); while (list($k, $v) = each($m)) { if (!isset($this->varkeys[$v])) { if ($this->debug & 4) { echo"get_undefined: undefined: $v \n"; } $result[$v] = $v; } } //如是该数组不为空就返回该数组,否则就返回错误
if (count($result)) { return $result; } else { return false; } }
//完成对str的最后的处理工作,利用类的属性unknowns来确定对模板中无法处理的动态部分的处理方法
function finish($str) { switch ($this->unknowns) { case "keep": //保持不变
break;
case "remove": //删除所有的非控制符
$str = preg_replace('/{ [^ \t\r\n }]+ }/', "", $str); break;
case "comment": //将大括号中的HTML注释
$str = preg_replace('/{ ([^ \t\r\n }]+) }/', "", $str); break; }
return $str; }
//将参数变量对诮的数组中的值处理后输出
function p($varname) { print $this->finish($this->get_var($varname)); }
//将参数变量对应的数组中的值处理后返回
function get($varname) { return $this->finish($this->get_var($varname)); }
//检查并补充给定的文件名
function filename($filename) { if ($this->debug & 4) { echo"filename: filename = $filename \n"; } if (substr($filename, 0, 1) != "/") //如果文件名不是以斜杠开头,则表示是相对路径,将其补充为完整的绝对路径
{ $filename = $this->root."/".$filename; } //如果文件不存在
if (!file_exists($filename)) { $this->halt("filename: file $filename does not exist."); } return $filename; //返回文件名
}
//对变量名进行处理,将正则表达式中的敏感字符变为转义字符,并在变量名两端加上大括号
function varname($varname) { return preg_quote("{ ".$varname." }"); }
//该方法根据varname加载文件到键一值对中
function loadfile($varname) { if ($this->debug & 4) { echo"loadfile: varname = $varname \n"; }
if (!isset($this->file[$varname])) //如果没有指定就返加错误
{ // $varname does not reference a file so return
if ($this->debug & 4) { echo "loadfile: varname $varname does not reference a file \n"; } return true; }
if (isset($this->varvals[$varname])) //如果已经加载了varname为名柄的文件,直接返回真值
{ if ($this->debug & 4) { echo"loadfile: varname $varname is already loaded \n"; } return true; } $filename = $this->file[$varname]; //句柄有效则取出对应的文件名
$str = implode("", @file($filename)); //将文件的每一行连接成一个字符串
if (empty($str)) //字符串空说明文件空或者不存在,返回错误
{ $this->halt( "loadfile: While loading $varname, $filename does not exist or is empty."); return false; } if ($this->debug & 4) { printf("loadfile: loaded $filename into $varname \n"); } $this->set_var($varname, $str); //如果文件不为空,用$varname作为句柄,str为变量名
//向键值对中添加新的键值
return true; }
//将分析结果保存到文件中去
function savetofile($dir, $varname) { $data = $this->finish($this->get_var($varname)); $fp = fopen($dir, "w+"); fwrite($fp, $data); }
//清除已赋值数组
function renew() { $this->varkeys = array(); $this->varvals = array(); $this->file = array(); }
//出错提示并终止程序运行
function halt($msg) { $this->last_error = $msg;
if ($this->halt_on_error != "no") { $this->haltmsg($msg); }
if ($this->halt_on_error == "yes") { die("终止."); }
return false; }
//出错提示
function haltmsg($msg) { printf("模板错误: %s \n", $msg); }
}
?>
|