PHP-关于模板的原理和解析

来源:转载

此内容用作笔记,以备日后查看,此内容为学习李炎恢课程而来,并非自己所创,如有问题请私信~

将PHP代码和静态HTML代码进行分离,使代码的可读性和维护性得到显著提高。

使用模板引擎:

    我们所说的模板是Web模板,是主要由HTML标记组成的语言来编写的页面,但也有如何表示包含动态生成内容的方式(解析标签)。模板引擎是一种软件库,允许我们从模板生成HTML代码,并指定要包含的动态内容。

模板引擎的特点:

1.鼓励分离:让更个系统的可读性和维护性得到提高。

2.促进分工:使得程序员和美工去专心处理自己的设计。

3.比PHP更容易解析:编译文件和缓存文件加载更快、占资源更少。

4.增加安全性:可限制模板设计师进行不安全的操作的能力避免误删误访问等。

模板处理的流程图

 

创建模板:

1、创建初始模板所需要的文件夹和文件。

a) index.php主文件,用于编写业务逻辑。

b) template.inc.php模板初始化文件,用于初始模版信息。

c) templates目录存放所有的模板文件。

d) templates_c目录存放所有编译文件。

e) cache目录存放所有缓存文件。

f) includes目录存放所有的类文件。

g) config目录存放模板系统变量配置文件。

以下是源码:

主文件 index.php

php

//index.php

//设置编码为UTF-8

header('Content-Type:text/html;Charset=utf-8');

//网站根目录

define('ROOT_PATH', dirname(__FILE__));

//存放模板文件夹

define('TPL_DIR', ROOT_PATH.'/templates/');

//编译文件夹

define('TPL_C_DIR', ROOT_PATH.'/templates_c/');

//缓存文件夹

define('CACHE_DIR', ROOT_PATH.'/cache/');

//定义缓存状态

define('IS_CACHE',true);

//设置缓存状态开关

IS_CACHE ? ob_start() : null;


include ROOT_PATH.'/includes/Templates.class.php';

$_name = '方块李';

$array = array(1,2,3,4,5,6);

$_tpl = new Templates();

$_tpl->assign('name', $_name);

$_tpl->assign('a', 5>4);

$_tpl->assign('array', $array);

//显示

$_tpl->display('index.tpl');

?>

模板文件 HTML

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

DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>title>

 

head>

<body>

{include "test.php"}


{#}这是一条PHP的注释,在HTML页面里是不显示的,只会在生成的编译文件里显示{#}

我将被index.php导入

{$name}这个标签必须经过Parser.class.php这个解析类来解析它1

<br />

这里的内容改变了,为什么?

<br />

{if $a}

显示一号皮肤

{else}

显示二号皮肤

{/if}

<br />

{foreach $array(key,value)}

{@key}....{@value} <br />

{/foreach}

body>

html>





模板类:

+ View Code




解析类:

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

//Parser.class.php

    class Parser {

        //获取模板内容

        private $_tpl;

        //构造方法,初始化模板

        public function __construct($_tplFile){

            //判断文件是否存在

            if(!$this->_tpl = file_get_contents($_tplFile)){

                exit('ERROR:读取模板出错!');

            }

            

        }

        

        //解析普通变量

        private function parVar(){

            $_pattern '/\{\$([\w]+)\}/';

            if (preg_match($_pattern,$this->_tpl)) {

                $this->_tpl = preg_replace($_pattern,"_vars['$1'] ?>",$this->_tpl);

            }

        }

        //解析IF条件语句

        private function parIf(){

            //开头if模式

            $_patternIf '/\{if\s+\$([\w]+)\}/';

            //结尾if模式

            $_patternEnd '/\{\/if\}/';

            //else模式

            $_patternElse '/\{else\}/';

            //判断if是否存在

            if(preg_match($_patternIf$this->_tpl)){

                //判断是否有if结尾

                if(preg_match($_patternEnd$this->_tpl)){

                    //替换开头IF

                    $this->_tpl = preg_replace($_patternIf"_vars['$1']){ ?>"$this->_tpl);

                    //替换结尾IF

                    $this->_tpl = preg_replace($_patternEnd""$this->_tpl);

                    //判断是否有else

                    if(preg_match($_patternElse$this->_tpl)){

                        //替换else

                        $this->_tpl = preg_replace($_patternElse""$this->_tpl);

                    }

                }else{

                    exit('ERROR:语句没有关闭!');

                }

            }

        }

        //解析foreach

        private function parForeach(){

            $_patternForeach '/\{foreach\s+\$(\w+)\((\w+),(\w+)\)\}/';

            $_patternEndForeach '/\{\/foreach\}/';

            //foreach里的值

            $_patternVar '/\{@(\w+)\}/';

            //判断是否存在

            if(preg_match($_patternForeach$this->_tpl)){

                //判断结束标志

                if(preg_match($_patternEndForeach$this->_tpl)){

                    //替换开头

                    $this->_tpl = preg_replace($_patternForeach"_vars['$1'] as \$$2=>\$$3){?>"$this->_tpl);

                    //替换结束

                    $this->_tpl = preg_replace($_patternEndForeach""$this->_tpl);

                    //替换值

                    $this->_tpl = preg_replace($_patternVar""$this->_tpl);

                }else{

                    exit('ERROR:Foreach语句没有关闭');

                }

            }

        }

        //解析include

        private function parInclude(){

            $_pattern '/\{include\s+\"(.*)\"\}/';

            if(preg_match($_pattern$this->_tpl,$_file)){

                //判断头文件是否存在

                if(!file_exists($_file[1]) || empty($_file[1])){

                    exit('ERROR:包含文件不存在!');

                }

                //替换内容

                $this->_tpl = preg_replace($_pattern""$this->_tpl);

            }

        }

        //解析系统变量

        private function configVar(){

            $_pattern '//';

            if(preg_match($_pattern$this->_tpl,$_file)){

                $this->_tpl = preg_replace($_pattern,"_config['$1'] ?>"$this->_tpl);

                

            }

        }

        

        //解析单行PHP注释

        private function parCommon(){

            $_pattern '/\{#\}(.*)\{#\}/';

            if(preg_match($_pattern$this->_tpl)){

                $this->_tpl = preg_replace($_pattern""$this->_tpl);

            }

        }

        

        

        //生成编译文件

        public function compile($_parFile){

            //解析模板变量

            $this->parVar();

            //解析IF

            $this->parIf();

            //解析注释

            $this->parCommon();

            //解析Foreach

            $this->parForeach();

            //解析include

            $this->parInclude();

            //解析系统变量

            $this->configVar();

            //生成编译文件

            if(!file_put_contents($_parFile$this->_tpl)){

                exit('ERROR:编译文件生成失败!');

            }

        }

    }





总结:模板引擎的整个过程:

1、当浏览器请求index.php文件时,实例化模板类对像 $_tpl = new Templates();

2、当Templates实例化的时候,生成两个数组,一个用来存放模板变量,另一个存放系统变量,通过构造方法,判断文件夹是否存在,同时通过XML文件将系统变量数组初始化

3、通过模板类Templates的注入方法,assign(),将对应模板index.tpl中变量的index.php的内容注入到模板类的私有变量,完成初始化

4、模板类Templates类显示方法display() 通过实例化解析类Parser,将取到的注入变量通过解析类进行解析(即替换)

5、解析(替换)后,将文件写入PHP、HTML混全文件

6、通过Templates类的显示方法将文件输出:

1、第一次执行显示方法时,将会把PHP、HTML混合文件,生成纯静态的缓存文件

2、调用缓存文件,显示页面

3、当浏览器再次调用显示方法时,首先根据各文件的最后修改时间,判断是否重新生成缓存文件或直接调用已存在的缓存文件

重点:

1、通过正则表达式进行字符串的替换

2、熟悉OOP




php原理

php模板

php模板原理

分享给朋友:
您可能感兴趣的文章:
随机阅读: