视图

视图,你所看见的部分。

  1. <?php
  2. echo 'hello, world';

从简单开始理解

这就是个视图文件中的代码,没错就这么简单。视图,实际上是在 MVC 这种架构上提出的。MVC 中,视图负责呈现数据。因此可以说只要是输出了数据的,都叫做视图。

在没有使用框架的时候,业务逻辑、数据的读写、组织和展示都是在一堆代码里,难以剥离,随着项目增大变得越来越难以维护。MVC 有效的分离了三者,各司其职。视图作为呈现数据的,只负责组织、展示,不再负责读写和业务逻辑。

既然视图只负责呈现数据,那么单独成一个文件,这个文件内的代码绝对不要读取数据库、做业务判断,那么就算你将视图独立出来了。这时候大多数人会想到,视图中的数据从哪来呢?

我们以一个简单的例子实现一个业务逻辑和视图分离的结构。

文件 controller.php,代码如下

  1. <?php
  2. $time = time();
  3. $string = ($time % 2) == 0 ? '偶数' : '奇数';
  4. // 加载视图
  5. include 'view.php';

文件 view.php,代码如下

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>视图实例</title>
  6. </head>
  7. <body>
  8. <p>时间戳 <?=$time?> 是 <?=$string?></p>
  9. </body>
  10. </html>

代码写好,运行后结果是预期的,对吗?

这两个文件中,毋庸置疑 view.php 就是视图文件,而 controller.php 你可以当做一个控制器,因为它实现了主要的业务逻辑(虽然极其简单)。尽管简洁,但在结构上我们已经完全分离。

事实上,目前所有的框架的视图的实现都大致如此,没什么特别的、神秘的地方,只是说框架它做了更多的事,比如验证视图文件的合法性、通过更少的参数去加载视图等等。

如何传递一个变量到视图文件?

我相信很多人在这个上面有着很多的疑惑。比如我们常看到这样向视图传递变量:

  1. // laravel 通过视图类的 with 方法传递
  2. View::make('view')->with('value', '实际的数据');
  3. // Smarty 模板引擎通过 assign 方法向最终的编译好的视图传递变量
  4. $smarty->assign('value', '实际的数据');
  5. // ...

实际上,在上面的逻辑与视图分离的例子中已经说了。当 include 或 require 一个文件时,该文件会继承引入他的那段代码的作用域。php 官方文档是这么说的:

当一个文件被包含时,其中所包含的代码继承了 include 所在行的变量范围。从该处开始,调用文件在该行处可用的任何变量在被调用的文件中也都可用。不过所有在包含文件中定义的函数和类都具有全局作用域。

如果 include 出现于调用文件中的一个函数里,则被调用的文件中所包含的所有代码将表现得如同它们是在该函数内部定义的一样。所以它将遵循该函数的变量范围。此规则的一个例外是魔术常量,它们是在发生包含之前就已被解析器处理的。

实战 —— 实现一个视图类

假设我们有一个视图类,定义在文件 View.php

  1. <?php
  2. class View
  3. {
  4. protected $data = [];
  5. public function display($file)
  6. {
  7. extract($this->data);
  8. include $file;
  9. }
  10. public function assign($key, $value)
  11. {
  12. $this->data[$key] = $value;
  13. }
  14. }

我们现在有模板文件,定义在文件 Template.php:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title><?=$title?></title>
  5. <meta charset="utf-8">
  6. </head>
  7. <body>
  8. <h1><?=$title?></h1>
  9. <p>
  10. <?=$content?>
  11. </p>
  12. </body>
  13. </html>

然后我们的主要业务逻辑代码如下:

  1. <?php
  2. // 包含视图类文件
  3. include 'View.php';
  4. $view = new View();
  5. $view->assign('title', '视图测试');
  6. $view->assign('content', '这是一个视图类的示例');
  7. $view->display('Template.php');

输出的内容大家都已经看得出来了,我就不截图了。

至此,大家应该都明白如何实现一个视图了吧?其实原理就这么简单。

模板引擎

模板引擎的诞生实际上是将视图拆分出来以后的事儿。大家看到了,上面例子中,所有模板中的变量,都是通过原生的 php 语法进行输出。假如单纯是输出内容,其实不用模板引擎也可以,但是一旦涉及到需要复用模板或者对视图文件进行模块化的拆分,实现诸如继承、布局之类的功能时,原生的 php 语法似乎需要写更为复杂的代码才能实现。

很显然,我们不应该在视图文件内写超出职责或过于繁杂的额外代码,因此,模板引擎就显得十分必要。

模板引擎的用处并不是所谓的方便前端的美工和网页设计师,因为原生的语法比很多模板引擎语法更为简洁。实际上,模板引擎最主要的任务是简化在视图上的额外代码,比如处理布局、模板继承等等。

说了那么多,如何实现模板引擎?

其实模板引擎就是将一个指定的模板标记通过正则匹配,替换成相应的合法 php 语句而已。

php实现简单视图模板(视图引擎)的更多相关文章

  1. ASP.NET WEB应用程序(.network4.5)MVC Razor视图引擎2 视图模板页

    https://www.cnblogs.com/xlhblogs/archive/2013/06/09/3129449.html MVC Razor模板引擎 @RenderBody.@RenderPa ...

  2. AspNet MVC与T4,我定制的视图模板

    一. 遇到的问题 文章开头部分想先说一下自己的困惑,在用AspNet MVC时,完成Action的编写,然后添加一个视图,这个时候弹出一个添加视图的选项窗口,如下: 很熟悉吧,继续上面说的,我添加一个 ...

  3. Solon Web 开发,七、视图模板与Mvc注解

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

  4. laravel4通过控制视图模板路劲来动态切换主题

    通过控制视图模板路劲来动态切换主题 App::before(function($request) { $paths = Terminal::isMobile() ? array(__dir__.'/v ...

  5. vs 2013下自定义ASP.net MVC 5/Web API 2 模板(T4 视图模板/控制器模板)

    vs 2013下自定义ASP.net MVC 5/Web API 2  模板(T4 视图模板/控制器模板): Customizing ASP.NET MVC 5/Web API 2 Scaffoldi ...

  6. ThinkPHP框架视图详细介绍 View 视图--模板(九)

    原文:ThinkPHP框架视图详细介绍 View 视图--模板(九) 视图也是ThinkPHP使用的核心部分: 一.模板的使用 a.规则 模板文件夹下[TPL]/[分组文件夹/][模板主题文件夹/]和 ...

  7. PHP Lavavel 使用控制器 传递变量 以及调用 视图模板

    控制器第一次入门使用 位置: 在app/Http/Controllers 目录下创建文件名格式:例如 UserController路由调用格式:Route::get('user/tom','UserC ...

  8. 【SQL模板】二.创建表视图模板TSQL

    ---Name: 创建表视图模板.sql ---Purpose: 用于创建 数据库中 新的数据表/视图 ---Author: xx ---Time: 2015-12-18 10:26:06 ---Re ...

  9. Xamarin XAML语言教程模板视图TemplatedView(二)

    Xamarin XAML语言教程模板视图TemplatedView(二) (2)打开MainPage.xaml文件,编写代码,将构建的控件模板应用于中TemplatedView.代码如下: <? ...

随机推荐

  1. bzoj2442&&codevs4654 单调队列优化dp

    这道题也是一道单调队列 很明显满足各种性质 f[i]表示i不选前面k-1个都选的最小损失 维护的是个单增队列 q[head]是队列最小值 代码十分简介 注意longlong就okay #include ...

  2. python反爬之动态字体相关文档

    web_font的一些基本原理 https://blog.csdn.net/fdipzone/article/details/68166388 实例1 猫眼电影 http://www.cnblogs. ...

  3. Spark优化之一:分布式下的map操作是闭包

    例如对一个JavaPairRDD<String, String>做遍历操作,常见的,我们可以通过先通过collect()操作将它转化为Map对象再进行遍历,也可以使用Spark提供的map ...

  4. python的上下文管理(context)(1)

    本文转载自:http://blog.csdn.net/G_66_hero/article/details/53048540 什么是Python中的上下文管理器 怎么使用上下文管理器 如何创建自己的上下 ...

  5. matlab保存图片成eps格式不全,导致latex中图片显示不全的问题

    我们经常会遇到这样的问题.用将matlab生成的图保存EPS格式后,用GSVIEW打开后,可以看到图片显示不全.遇到这种情况是,我们可以使用dvipdf——dvips的方法来生成PDF,这样生成的pd ...

  6. AC日记——[ZJOI2007]报表统计 bzoj 1058

    1058 思路: 平衡树的题: 然而我的平衡树写一次炸一次QwQ: 而且各种tle: 所以stl水过: 代码: #include <set> #include <cstdio> ...

  7. 大数据技术之_16_Scala学习_07_数据结构(上)-集合

    第十章 数据结构(上)-集合10.1 数据结构特点10.1.1 Scala 集合基本介绍10.1.2 可变集合和不可变集合举例10.2 Scala 不可变集合继承层次一览图10.2.1 图10.2.2 ...

  8. The 15th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple - L Doki Doki Literature Club

    Doki Doki Literature Club Time Limit: 1 Second      Memory Limit: 65536 KB Doki Doki Literature Club ...

  9. poj2778(AC 自动机)

    poj2778 题意 构造只包含 \(A, T, C, G\) 的字符串,且满足不出现指定的一些字符串,问长度为 \(n\) 的字符串有多少种 ? 分析 AC 自动机 + 矩阵快速幂的神题 ,知识点很 ...

  10. 树链剖分【p4114】Qtree-Query on a tree I

    Description 给定一棵n个节点的树,有两个操作: CHANGE i ti 把第i条边的边权变成ti QUERY a b 输出从a到b的路径中最大的边权,当a=b的时候,输出0 Input 第 ...