PHPWind 的模板解析主要发生在 ./template/wind 目录下,核心的解析引擎是 WindTemplate 类。

phpwind 模板解析在哪
(图片来源网络,侵删)

下面我将从 “文件位置”、“核心原理”、“解析过程”“如何自定义” 四个方面为你详细拆解。


模板文件在哪里?

你需要知道模板文件本身存放在哪里,PHPWind 的模板文件位于:

./template/wind/

这个目录下会根据不同的应用(如首页、论坛、个人空间等)分门别类地存放。

  • ./template/wind/header.htm : 页面头部
  • ./template/wind/foot.htm : 页面底部
  • ./template/wind/index/index.htm : 首页模板
  • ./template/wind/read/htm/read.htm : 帖子阅读页模板
  • ./template/wind/user/htm/login.htm : 用户登录页模板

注意

phpwind 模板解析在哪
(图片来源网络,侵删)
  • ./template/wind/系统默认模板 的目录。
  • 如果你在后台安装了其他模板,它们会被存放在 ./template/ 下的其他自定义文件夹中,./template/mynewtheme/
  • 模板文件的后缀通常是 .htm.html,这只是为了方便编辑,它们本质上就是 PHP 文件。

核心解析类与原理

PHPWind 的模板解析引擎是一个独立的、强大的组件,核心类是 WindTemplate

核心原理: “编译”而非“实时解析”

这是 PHPWind 模板引擎最关键的设计思想,也是其性能较高的原因。

  • 传统实时解析:每次访问页面时,程序都去读取 .htm 文件,然后逐行解析其中的模板标签(如 {loop}),再替换成真实数据,这样每次请求都要做大量的字符串替换,非常慢。
  • PHPWind 的编译模式
    1. 首次请求:当一个模板文件(如 index.htm)被访问时,PHPWind 的模板引擎会读取这个 .htm 文件。
    2. 编译:引擎会解析 .htm 文件中的所有特殊标签(如变量、循环、条件判断等),并将其转换成 标准的 PHP 代码
    3. 生成编译文件:这个转换后的 PHP 代码会被保存成一个新文件,通常存放在 ./data/template/ 目录下。./template/wind/index/index.htm 编译后可能会生成 ./data/template/wind/index/index.php
    4. 后续请求:当再次访问这个页面时,PHPWind 会直接跳过解析 .htm 文件的步骤,直接执行编译好的 ./data/template/.../index.php 文件,因为 PHP 代码的执行效率远高于字符串解析,所以速度极快。

.htm 文件是给开发者看的“源代码”,而编译后的 .php 文件是给 PHP 引擎执行的“机器码”。

phpwind 模板解析在哪
(图片来源网络,侵删)

解析过程详解

一个完整的模板渲染流程如下:

  1. 入口:当用户访问一个 URL 时,PHPWind 的路由系统会确定哪个控制器和方法来处理这个请求。

  2. 模板赋值:在控制器的方法中,开发者会先获取需要展示的数据(如从数据库读取帖子列表、用户信息等),然后通过 $this->setOutput('变量名', '变量值') 或类似的方法,将这些数据传递给模板引擎,这些数据通常被存放在一个 WindView 对象中。

  3. 模板实例化与解析

    • 控制器会指定要使用的模板文件,index.htm
    • WindTemplate 引擎被实例化。
    • 引擎会检查 ./data/template/ 目录下是否存在对应模板的 编译文件(如 index.php)。
      • 如果编译文件存在且未过期:直接执行这个编译文件,并把之前赋值的变量传递给它,生成最终的 HTML 页面并输出到浏览器。
      • 如果编译文件不存在或源模板文件已修改: a. 读取源模板文件 ./template/wind/index/index.htm。 b. 遍历文件内容,解析所有模板标签。 c. 将标签替换成对应的 PHP 代码。 d. 将生成的新 PHP 代码写入到 ./data/template/.../index.php 文件中(编译缓存)。 e. 执行这个新生成的编译文件,输出 HTML。

常见的模板标签及其编译后的 PHP 代码示例:

模板标签 说明 编译后的 PHP 代码示例
{变量名} 输出一个变量 <?php echo $this->getOutput('变量名'); ?>
{loop $数组 $key $value} 循环遍历数组 <?php foreach ((array)$this->getOutput('数组') as $key => $value) { ?>
{/loop} 循环结束 <?php } ?>
{if $条件} 条件判断 <?php if ($this->getOutput('条件')) { ?>
{/if} 条件结束 <?php } ?>
{template header} 引入另一个模板 <?php $this->render('header'); ?>

如何找到和自定义解析?

A. 如何找到解析代码?

  • 核心文件./wind/core/template/WindTemplate.php,这是模板引擎的主类,所有解析逻辑都在这里。
  • 视图类./wind/core/WindView.php./wind/core/web/WindWebView.php,它们负责协调控制器和模板引擎,调用 WindTemplate 来完成渲染任务。
  • 工具类./wind/core/utility/WindTemplateCompiler.php,这个类(或类似名称的类)专门负责将 .htm 标签编译成 .php 代码。

你可以通过搜索 WindTemplate 类的 compilerender 方法来追踪整个流程。

B. 如何自定义或扩展模板功能?

  1. 修改编译规则

    • 如果你想添加自定义的模板标签({mytag ...}),你需要修改 WindTemplateCompiler 类,为其添加新的编译规则,告诉引擎遇到 {mytag} 时应该生成什么样的 PHP 代码。
  2. 修改模板目录

    • WindView 类中,你可以通过设置 $templateDir 属性来改变模板的根目录,这通常在应用初始化或切换主题时完成。
  3. 性能优化

    • 清理编译缓存:当你修改了模板文件但看不到效果时,最直接的方法是删除 ./data/template/ 目录下的对应编译文件,下次访问时会自动重新编译。
    • 关闭模板缓存:在开发调试阶段,你可以在配置文件中设置模板引擎的缓存为关闭状态,这样每次修改模板文件后都能立即看到效果,但性能会很低,配置项通常类似 'templateCache' => false

希望这个详细的解释能帮助你完全理解 PHPWind 的模板解析机制!