Chinaunix首页 | 论坛 | 博客
  • 博客访问: 970805
  • 博文数量: 120
  • 博客积分: 6454
  • 博客等级: 准将
  • 技术积分: 1739
  • 用 户 组: 普通用户
  • 注册时间: 2007-06-28 17:45
文章分类

全部博文(120)

文章存档

2014年(1)

2013年(1)

2012年(11)

2011年(16)

2010年(6)

2009年(11)

2008年(30)

2007年(44)

分类:

2007-12-21 10:41:11

<?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);
  }

}

?>

阅读(2069) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~