摘 要:在一些中型甚至大型的项目中,有效的将HTML(还有其他文本形式的表现层)和PHP代码分开,不仅在开发阶段可以分别提高界面设计人员和应用程序编写人员的工作效率,更会给项目的测试和维护带来巨大的便利。本文将简要介绍了PHP Template,以及如何在PHP项目中引用PHPLIB Template,实现HTML、Javascript、CSS代码和 PHP 代码分离。
关键词:php template,phplib
1. 模板技术由来
现在互联网上流行着很多优秀的嵌入式的脚本语言,例如perl,php,asp,jsp等。其中最流行的一种就是php,它以全部公开代码、开发容易、跨平台、功能强大以及支持数据库类型繁多等特点赢得了网上众多程序员的青睐。
而随着php的应用和推广,php的众多开发人员和很多爱好者在php的基础上开发了很多php的程序库,这些程序库包括了大量的类、方法、变量和方法,能够处理复杂的web资源和提供强大的功能,大大简化了程序设计和提高了代码的可重用性。
使用PHP编程的人都会碰到这样一个问题:当PHP代码和HTML代码在一起的时候,看PHP代码很费劲,整个文件也无法用Dreamweaver来编辑,这对于PHP程序员和美工来讲,修改这样的文件就象一个噩梦。
PHP中的模板(Template)技术就是为了解决这个问题而出现的。PHP模板类有很多,比较常见的是 FastTemplate 和 PHPLIB ,因为出现得早,在PHP编程界名声很大。
其中PHPLIB就是这些库中相当优秀的产品,它特别在数据库访问、数据库驱动以及访问认证和模板等方面具有很高的价值和实用性,用来开发大中型程序是相当适合的。
2. PHPLIB Template基本功能介绍
PHPLIB包含了很多功能,提供了众多的函数:
1. 将数据库驱动和对数据库操作完全分离。这样的好处是对数据库的操作,需要的知识仅仅是SQL语言,而不需要去估计各个不同数据库间的函数不同。如果需要将程序移植的话,那么PHPLIB的优势非常明显。需要修改的仅仅是数据库驱动文件,而程序行几乎都不需要修改任何一行。如果是采用具体数据库函数操作的程序(例如用MySQL函数编写),那么移植起来几乎是等于重新编写。
2. 支持Session。这个功能可以创建一个受保护的页面。它可以广泛的应用到需要进行登陆或者依靠账号和权限来判别的程序。例如论坛、虚拟社区、新闻发布、用户管理、电子商务等。而且这个和纯粹的cookie不同,采用了base_64的编码和解码。因此一般并不容易破译。为了加强安全性,用户可以自己编写自己的编码方式取代它原来的编码方式。同时PHPLIB还将每一个会话都保存到数据库中,因此可以通过查询数据库值得有多少用户在线上。
3. 权限许可(Perm)。这个功能可以定义一系列具有不同级别和权限的用户。不需要编程人员额外地自己编写相应功能的代码就可以实现了分级管理和限制。同时可以利用PHPLIB中page/admin目录中的管理程序创建用户和修改相关信息。编程人员可以修改这些程序来服务自己的系统,节省了大量时间。
4. 模板TEMPLATE,和FastTemplete类似的是,PHPLIB也有自己的模板功能类和文件。让用户可以方便的创建和修改HTML模板,并且将PHP代码和HTML代码分离,便于让程序员和美工良好的合作。PHPLIB的模板采用了定义标记和语法分析、模式匹配等技术,从而实现了和FastTemplete类似的功能。编程人员可以根据实际的需要对这个功能代码进行修改以满足自己需求。
5. 购物车Cart,这个是个比较简易的购物车,各种物品和项目可以存放到车中,也可以被取出来,通过一些改造后也可以将这个功能做成电子商务中流行的购物系统的。
6. HTML部件,在PHPLIB中还有一些称为“HTML Widgets”的东西,可以方便地生成窗口/表格等。具体可以参考PHPLIB手册。
3. PHPLIB安装
3.1 下载PHPLIB安装文件
安装,其实就是下载PHPLIB库文件。
1. 在PHPLIB的官方网站下载最新的版本:http://sourceforge.net/projects/phplib/files/
2. 解压缩后,里面有一个php文件夹,存放的是PHPLIB库文件,将该php文件夹复制到任何你想要的其它位置,但不要放在网页服务器的目录下。比如:网页服务器根目录是:/var/www,可以将php文件夹放在/var下,与www文件夹平行。
3.2 引入PHPLIB
3.2.1方法一:直接安装
采用phplib建议的安装方式,说安装,其实就是把PHPLIB的类预先让解析器加载到内存,这样使用的时候就不需要做任何设置,这样的好处显而易见。不过缺点也是很多的,如果程序按照这个方式直接引用PHPLIB的函数的话,对于一些采用虚拟主机的用户来说,如果ISP的服务器没有安装PHPLIB的话,就不可以直接使用PHPLIB了。所以这个方式的前提是:你的ISP支持PHPLIB或者你有权限控制web服务器,对于一般用户在自己机器上调试的话,这个方式比较好。
步骤:
1. 打开php.ini, 找到 include_path字段,如下所示:
; UNIX: "/path1:/path2" ;include_path = ".:/php/includes" ; ; Windows: "\path1;\path2" ;include_path = ".;C:/AppServ/includes" |
n 如果WEB服务器安装在UNIX(或者Linux)系统,则将第一个include_path所在行的行首的“;”去掉,并将等号右边双引号中“:”后的路径改为php文件夹的路径。
例如:php文件夹所在路径为: /var/php, 则include_path = ".:/var/php"
n 如果WEB服务器安装在windows系统,则将第二个include_path所在行的行首的“;”去掉,并将等号右边双引号中“;”后的路径改为php文件夹的路径。
例如:php文件夹所在路径为: D:/var/php, 则include_path = ".;D:/var/php"
2. 保存php.ini文件,并重启WEB服务器。
3.2.2方法二:包含方式
这个方式就是比较麻烦,但是好处就是对于使用虚拟主机的用户来说,可以不需要ISP支持PHPLIB就能享受PHPLIB的功能。
基本方法很简单,可以在使用到PHPLIB功能的程序最顶部加入相应的包含文件。不过要注意文件之间的相互依赖关系,下面是一个简单例子,它可以调用到基本的MySQL数据库驱动功能和Session功能:
$LIBDIR = " /usr/local/phplib "; require($LIBDIR . "db_mysql.inc"); require($LIBDIR . "ct_sql.inc"); require($LIBDIR . "session.inc"); require($LIBDIR . "local.inc"); require($LIBDIR . "page.inc"); |
4. PHPLIB Template功能
在Smartband项目中,因为服务器端口开发的是REST接口,只需要引入PHPLIB的Template功能即可,不需要使用到PHPLIB的其他功能。所以下面简单介绍一下如何使用模板功能。
在模板中,主要涉及到以下几方面的设置:
1. 变量的设置
很明显,{FOO}或者{BAR}的形式在两种模板中都是指定的形式(HTML文件中间含有将要被替换的以{}标识的变量)。
2. 模板类的初始化(类的构建器)
需要在构建模板类的时候指定模板文件存在的目录位置。
3. 变量的替换
模板处理中最常用的就是变量替换:可以采用(key, value)的方式,也可以直接传递一个数组(array(key=>value))。
4. 模板文件的处理
采用为每一个模板文件指定一个句柄(handler)的办法,同时句柄也可以作为变量的值替换另一模板文件中的变量。
5. 解析、输出过程
需要调用parse()方法将需要输出的模板文件解析后赋值给一个句柄,然后调用输出的方法输出该句柄的内容并结束处理。
6. 重复解析的过程
比如从数据库中取出几条记录需要显示而模板文件只有可替换的一行变量的时候,就很需要这样的功能。
7. 区块解析的过程(或者可以称作动态解析)
想象一下,你需要从数据库中取出符合条件的数据并显示在网页中(但是因为条件会不尽相同,你并不能明确的知道会有多少条数据)这时候如果你又要采用模板,那么区块就是最好的选择。它是在模板中用特定的符号定义的部分,这一部分可以反复的被解析并添加到(而不是前一次的解析被后一次覆盖)输出网页中。
4.1 设置模板变量
first.html:模板中的{man}{author}可以称为“模板变量”,用花括号({})括起来
<HTML> <HEAD> <TITLE>我的第一个模板文件</TITLE> </HEAD> <BODY> 你知道吗? {man}真是一个好人。 <font color=”#cccccc”> 作者:{author}</font> </BODY> </HTML> |
上面定义三个变量的原因是需要随时改变它们的值,下面开始这个工作。
新建first.php文件,内容如下:
<?php include ('template.inc'); //包含进模板类 template.inc $tpl = new Template; //创建一个新模板 $tpl->set_file('main', 'first.html'); //把模板文件加载进来 $tpl->set_var('man', 'hello'); //给文件中的模板变量赋值 $tpl->set_var('author', ' hello'); $tpl->parse('mains', 'main'); // 完成替换 $tpl->p('mains'); // //输出替换的结果 ?> |
也可以一次完成给变量赋值,例如:
$tpl->set_var( array('man'=>' hello', author'=>' hello') ); |
在浏览器中浏览这个文件,输出:
你知道吗?hell真是一个好人。作者:hello |
4.2 使用block
second.html:模板文件中使用<!-- BEGIN block_nam--> <!-- END block_name --> 标记block的开始结束,其中!后面为两个中划线,BEGIN list和END block_name,与前后的中划线--之间必须有空格。
<HTML> <HEAD> <TITLE>seconde template</TITLE> </HEAD> <BODY> this is a table. <UL> <!-- BEGIN test --> <li>{name}的身高{tall}</li> <!-- END test --> </UL> </BODY> </HTML> |
second.php:
<?php include ('template.inc'); $tpl = new Template; $tpl->set_file('main', 'second.html'); $tpl->set_block('main', 'test', 'nlist'); //加载模板main中的块list,并给其一个名字nlist
// 赋值,此处模拟从DB中取值 $a = array(); for($i = 0; $i < 10; $i++){ $b = array('name' => 'name_'.$i, 'tall' => 'tall_'.$i); $a[] = $b; }
foreach ($a as $item) { $tpl->set_var('name' , $item['name']); $tpl->set_var('tall' , $item['tall']); $tpl->parse('nlist', 'test', true); } $tpl->parse('mains', 'main'); $tpl->p('mains'); ?> |
4.3 block嵌套
在实际应用中,单层block不能满足应用。这时候就要使用多重block。需要注意循环赋值的重置。
seconde.html
<table border="1"> <!-- BEGIN row --> <tr> <!-- BEGIN col --> <td>{NUM}</td> <!-- END col --> </tr> <!-- END row --> </table> |
seconde.php
include("template.inc"); $t =new Template("."); $t->set_file ("main","seconde.html"); $t->set_block ("main","row","mrow"); $t->set_block ("row","col","mcol"); for ($i=1;$i<5;$i++) { for ($j=1;$j<5;$j++) { $num=$i*$j; $code=$i.'*'.$j.'='.$num; $t->set_var ("NUM","$code"); $t->parse ("mcol","col",true); } $t->parse ("mrow","row",true); $t->set_var(‘mcol’); //清空变量,避免值重复; } $t->parse ("out","fHandle"); $t->p("out"); |
4.4 模板嵌套
third.html:
<!-- 这是页面头部 --> {header} <BODY> 下面是一个列表 <UL> <!-- BEGIN list --> <li>{name} 的身高是 {tall}</li> <!-- END list --> </UL> <!– 这是页脚部分 –> {footer} </BODY> </HTML> |
header.html:
<HTML> <HEAD> <TITLE>{title}</TITLE> </HEAD> |
footer.html:
<P>author © {author} |
third.php:
<?php include ('template.inc'); $tpl = new Template; $tpl->set_file('main', 'third.html'); $tpl->set_file('my_header', 'header.html'); $tpl->set_file('my_footer', 'footer.html'); $tpl->set_var('title', '这个是网页标题'); $tpl->set_var('author', '这个是作者'); $tpl->set_block('main', 'list', 'nlist');
for($i = 0; $i < 10; $i++){ $b = array('name' => 'name_'.$i, 'tall' => 'tall_'.$i); $a[] = $b; } foreach ($a as $item) { $tpl->set_var('name' , $item['name']); $tpl->set_var('tall' , $item['tall']); $tpl->parse('nlist', 'list', true); }
$tpl->parse('header', 'my_header'); $tpl->parse('footer', 'my_footer'); $tpl->parse('mains', 'main'); $tpl->p('mains'); ?> |
4.5 修改Template模板变量界定符
在PHPLIB中,默认以‘{}’界定模板变量,但在实际项目中,会与Javascript或者css等冲突。可以根据实际项目需要修改PHPLIB Template的模板变量界定符‘{}’。步骤如下:
1. 修改set_block函数
$reg = "/[ \t]*<!--\s+BEGIN $varname\s+-->\s*?\n?(\s*.*?\n?)\s*<!--\s+END $varname\s+-->\s*?\n?/sm"; preg_match_all($reg, $str, $m); if (!isset($m[1][0])) { $this->halt("set_block: unable to set block $varname."); return false; } $str = preg_replace($reg, "{" . $name . "}", $str); // 修改自定义的界定符。 |
2. 修改get_undefined 函数
preg_match_all( (("loose" == $this->unknown_regexp) ? "/{([^ \t\r\n}]+)}/" : "/{([_a-zA-Z]\\w+)}/"), // 修改自定义的界定符。 $this->get_var($varname), $m); |
3. 修改finish 函数
case "remove": $str = preg_replace( (("loose" == $this->unknown_regexp) ? "/{([^ \t\r\n}]+)}/" : "/{([_a-zA-Z]\\w+)}/"), // 修改自定义的界定符。 "", $str); break;
case "comment": $str = preg_replace( (("loose" == $this->unknown_regexp) ? "/{([^ \t\r\n}]+)}/" : "/{([_a-zA-Z]\\w+)}/"), // 修改自定义的界定符。 "<!-- Template variable \\1 undefined -->", $str); break; |
4. 修改varname 函数
return preg_quote("{" . $varname . "}"); // 修改自定义的界定符。 |
5. 保存文件,完成修改。