构建自己的PHP框架--构建模版引擎(2)
自从来到新公司就一直很忙,最近这段时间终于稍微闲了一点,赶紧接着写这个系列,感觉再不写就烂尾了。
之前我们说到,拿到{{ $name }}这样一段内容时,我们只需要将它转化成<?php echo $name ?>这样,就可以识别了,输出相应的变量值。
那就要需要正则匹配{{ $name }},然后替换掉{{和}},分别替换成<?php echo和?>。
但是要想到一个问题,如果我在 view 里写了 php 的代码,其中含有{{ $name }},也会被替换。例子如下:
<?php
$name = 'test';
$str = "{{ $name }}";
?>
要解决这个问题,我们需要将 PHP 的代码去掉,只留下 html 代码再做替换的处理。幸好 PHP 有一个方法 token_get_all,会将提供的内容按 PHP 标记进行分割。使用此方法解析如下内容:
$content = <<<VIEW
<?php
\$name = 'test';
\$str = "{{ \$name }}";
?>
<html>
<body>{{ \$name }}</body>
<html>
VIEW;
print_r(token_get_all($content));
这里$符号前加\是为了转移,在真正是现实不需要。结果如下:
Array
(
[0] => Array
(
[0] => 379
[1] => <?php
[2] => 1
)
[1] => Array
(
[0] => 382
[1] =>
[2] => 2
)
[2] => =
[3] => Array
(
[0] => 382
[1] =>
[2] => 2
)
[4] => Array
(
[0] => 323
[1] => 'test'
[2] => 2
)
[5] => ;
[6] => Array
(
[0] => 382
[1] =>
[2] => 2
)
[7] => =
[8] => Array
(
[0] => 382
[1] =>
[2] => 3
)
[9] => "
[10] => Array
(
[0] => 322
[1] => {{
[2] => 3
)
[11] => Array
(
[0] => 320
[1] => $name
[2] => 3
)
[12] => Array
(
[0] => 322
[1] => }}
[2] => 3
)
[13] => "
[14] => ;
[15] => Array
(
[0] => 382
[1] =>
[2] => 3
)
[16] => Array
(
[0] => 381
[1] => ?>
[2] => 4
)
[17] => Array
(
[0] => 321
[1] =>
<html>
<body>{{ $name }}</body>
<html>
[2] => 5
)
)
可以看到 PHP 相关的代码被解析了,我们只需要判断出是 html 代码,然后做替换就可以了。其中的321就是定义好的常量T_INLINE_HTML的值,标记解析出来的就是 html 代码。
我们定义view文件的后缀为sf,那我们就可以在controller/model/view目录下创建view.sf文件,内容如下
<?php
$title = 'It is a title';
$str = "{{ $title }}";
?>
<html>
<head>
<title>{{ $title }}</title>
<head>
<body>
<h2>{{ $str }}</h2>
<p>{{ $body }}<p>
</body>
</html>
然后我们来改造Controller中的render方法,代码如下
public function render($view, $params = [])
{
$file = '../views/' . $view . '.sf';
$fileContent = file_get_contents($file);
$result = '';
foreach (token_get_all($fileContent) as $token) {
if (is_array($token)) {
list($id, $content) = $token;
if ($id == T_INLINE_HTML) {
$content = preg_replace('/{{(.*)}}/', '<?php echo $1 ?>', $content);
}
$result .= $content;
} else {
$result .= $token;
}
}
$generatedFile = '../runtime/cache/' . md5($file);
file_put_contents($generatedFile, $result);
extract($params);
require_once $generatedFile;
}
修改actionView如下
public function actionView()
{
$this->render('site/view', ['body' => 'Test body information']);
}
访问 http://localhost/simple-framework/public/index.php?r=site/view ,得到如下页面

今天就先到这里。项目内容和博客内容也都会放到Github上,欢迎大家提建议。
code:https://github.com/CraryPrimitiveMan/simple-framework/tree/1.1
blog project:https://github.com/CraryPrimitiveMan/create-your-own-php-framework
构建自己的PHP框架--构建模版引擎(2)的更多相关文章
- 构建自己的PHP框架--构建模版引擎(1)
前段时间太忙,导致好久都没有更新博客了,今天抽出点时间来写一篇. 其实这个系列的博客很久没有更新了,之前想好好规划一下,再继续写,然后就放下了,今天再捡起来继续更新. 今天我们来说一下,如何构建自己的 ...
- 构建自己的PHP框架--构建模版引擎(3)
之前我们实现了最简单的echo命令的模版替换,就是将{{ $name }}这样一段内容替换成<?php echo $name ?>. 现在我们来说下其他的命令,先来回顾下之前的定义 输出变 ...
- 构建自己的PHP框架--构建缓存组件(1)
作为一个框架,我们还没有相应的缓存组件,下面我们就来构建我们的缓存组件. 先来定义一下接口,在 src 文件夹下创建 cache 文件夹,在cache文件夹下创建 CacheInterface.php ...
- 构建自己的PHP框架--构建缓存组件(2)
上一篇博客中使用文件实现了缓存组件,这一篇我们就使用Redis来实现一下,剩下的如何使用memcache.mysql等去实现缓存我就不一一去做了. 首先我们需要安装一下 redis 和 phpredi ...
- 构建自己的PHP框架(Twig模板引擎)
完整项目地址:https://github.com/Evai/Aier Twig 模板引擎 模版引擎 twig 的模板就是普通的文本文件,也不需要特别的扩展名,.html .htm .twig 都可以 ...
- 基于laravel框架构建最小内容管理系统
校园失物招领平台开发 --基于laravel框架构建最小内容管理系统 摘要 针对目前大学校园人口密度大.人群活动频繁.师生学习生活等物品容易遗失的基本现状,在分析传统失物招领过程中的工作效率低下. ...
- net 和Mono 构建的HTTP服务框架
Nancy是一个基于.net 和Mono 构建的HTTP服务框架,是一个非常轻量级的web框架. 设计用于处理 DELETE, GET, HEAD, OPTIONS, POST, PUT 和 PATC ...
- 基于Dubbo框架构建分布式服务(一)
Dubbo是Alibaba开源的分布式服务框架,我们可以非常容易地通过Dubbo来构建分布式服务,并根据自己实际业务应用场景来选择合适的集群容错模式,这个对于很多应用都是迫切希望的,只需要通过简单的配 ...
- 使用 SailingEase WinForm 框架构建复合式应用程序(插件式应用程序)
对于一些较小的项目,具备一定经验的开发人员应该能够设计和构建出便于进行维护和扩展的应用程序.但是,随着功能模块数量(以及开发维护这些部件的人员)的不断增加,对项目实施控制的难度开始呈指数级增长. Sa ...
随机推荐
- 泛型(CSDN转载)
函数的参数不同叫多态,函数的参数类型可以不确定吗? 函数的返回值只能是一个吗?函数的返回值可以不确定吗? 泛型是一种特殊的类型,它把指定类型的工作推迟到客户端代码声明并实例化类或方法的时候进行. 下面 ...
- less的基本操作
less的四大特性及示例 1.特性一(变量) less写法 @color:#ffffff: body{background-color:@color:} 生成的css body{background- ...
- JS模式--职责链模式
职责链模式的定义:使用多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象连成一条链, 并沿着这条链条传递下去,直到有一个对象处理它为止. var order500 = f ...
- stl_config.h基本宏
四.宏: (其实呢, 我们所有的宏都包含在了 "stl_config.h"头文件中.) //这些宏是怎么判断是否需要定义:是否有指定的宏,还有一些特定的编译器也可能支持. 4.1. ...
- HTML5 拖放(Drag 和 Drop)功能开发——基础实战
随着HTML5的普及度越来越高,现在写代码也遇到一些了,经过同事的点播开展了一次Dojo活动用以技术交流,我也乘此机会将HTML5的拖放功能整理了一下. 简介 拖拽(Drag/Drop)是个非常普遍的 ...
- 安装配置sentry服务
环境 系统环境:Centos6.7 Hadoop版本:CDH5.10 jdk版本:jdk7 注:本文并未集成kerberos组件 安装Sentry Server 选择安装hive的节点进行安装测试: ...
- maven(02)--简单的命令操作
使用maven有什么好处呢? 这个问题留到该文的末尾进行总结>v< maven测试 在上一篇文章中介绍了如何简单的编译一个java文件,执行mvn compile命令后,你会发现在你新建的 ...
- jQuery选择器的优点
jQuery选择器的优点 相信小伙伴们对选择器并不陌生,从css1到css3的选择器有很多,但是JQuery都能完美的支持,而且API操作起来也特别方便好用,在很大程度上精简了代码,节约了很多性能.那 ...
- Java内存模型四
volatile的特性 当我们声明共享变量为volatile后,对这个变量的读/写将会很特别.理解volatile特性的一个好方法是:把对volatile变量的单个读/写,看成是使用同一个锁对这些单个 ...
- 基本排序算法<二>
归并排序 归并排序,顾名思义,就是通过将两个有序的序列合并为一个大的有序的序列的方式来实现排序.合并排序是一种典型的分治算法:首先将序列分为两部分,然后对每一部分进行循环递归的排序,然后逐个将结果进行 ...