简介
本文件为 DouPHP 模板引擎的“内置函数(修饰器)”与“模板标签”使用文档。内容覆盖:
- 数据处理类:字符串处理、计数、大小写转换、替换、换行等
- 格式化类:日期时间格式化、通用字符串格式化、缩进、空白压缩
- URL 生成类:通过模板标签 {url} 构建站点链接,支持分页、参数合并与 nofilter 控制
- 输出与转义:变量输出时的全局 HTML 转义策略与 nofilter 用法
- 执行流程:从模板到编译再到运行期的调用链路与优先级
- 常见问题:参数缺失、非法路径、空值回退、时区与格式兼容等
项目结构
DouPHP 模板系统采用“编译式渲染 + 运行时修饰器”的设计:
- 模板源经 Lexer → Parser → CodeGenerator 编译为 PHP
- 运行期通过 RenderContext 分发修饰器(过滤器)
- URL 构建由 UrlBuilder 统一负责,模板侧通过 {url} 标签调用 route()
graph TB
A["模板源"] --> B["Lexer/Parser"]
B --> C["CodeGenerator"]
C --> D["编译产物(可缓存)"]
D --> E["RenderContext<br/>变量作用域"]
E --> F["FilterRegistry<br/>标准修饰器"]
E --> G["URL 构建<br/>route()/UrlBuilder"]
图表来源
- DouViewCompiler.php:90-104
- DouView.php:198-230
- FilterRegistry.php:21-63
- UrlTagCompiler.php:34-84
- UrlBuilder.php:26-94
章节来源
- DouView.php:24-82
- DouViewCompiler.php:39-104
- FilterRegistry.php:21-63
核心组件
- 模板引擎主类:负责变量作用域、编译管线、缓存与全局转义开关
- 编译器:将模板语法解析为 PHP,并注册内置标签编译器
- 修饰器注册表:以名称映射到 callable,运行期按名分发
- 标准修饰器集合:提供字符串、日期、计数、格式化等常用能力
- URL 标签编译器:将 {url} 编译为 route() 调用,支持分页与参数合并
- URL 构建器:统一生成站点 URL,遵循伪静态规则与短地址策略
章节来源
- DouView.php:24-82
- DouViewCompiler.php:172-204
- FilterRegistry.php:21-63
- StandardFilters.php:23-63
- UrlTagCompiler.php:25-84
- UrlBuilder.php:26-94
架构总览
模板渲染与 URL 生成的关键调用序列如下:
sequenceDiagram
participant T as "模板"
participant V as "DouView"
participant C as "DouViewCompiler"
participant R as "RenderContext"
participant F as "FilterRegistry"
participant U as "UrlTagCompiler"
participant RB as "UrlBuilder"
T->>V : fetch("模板名")
V->>C : compile(资源名, 源)
C-->>V : 编译后的PHP
V->>R : 绑定变量与作用域
R->>F : 按名调用修饰器(如 date_format|escape)
T->>U : {url link=... params=... page=...}
U->>RB : route(link, params, options)
RB-->>T : 完整URL
图表来源
- DouView.php:164-230
- DouViewCompiler.php:90-104
- FilterRegistry.php:21-63
- UrlTagCompiler.php:34-84
- UrlBuilder.php:26-94
详细组件分析
标准修饰器(内置函数)一览
以下修饰器在模板中通过“管道”形式使用,例如 {$value|truncate:50:'...'}。所有修饰器均为纯函数,返回新值,不修改原变量。
-
字符串处理
- truncate:UTF-8 安全的截断,支持省略号、是否断词、中间截取
- escape:多类型转义(html/htmlall/url/urlpathinfo/quotes/hex/hexentity/decentity/javascript/mail/nonstd)
- nl2br:换行转 <br/>
- strip_tags:去除 HTML 标签,可选择用空格替代
- replace:字符串替换
- spacify:字符间插入分隔符
- wordwrap:按长度自动换行
- lower/upper:大小写转换
- cat:拼接字符串
- indent:每行前添加缩进
- strip:压缩空白为单字符
-
计数与统计
- count_characters:统计字符数(可选包含空格)
- count_paragraphs:统计段落数
- count_sentences:统计句子数
- count_words:统计单词数
-
格式化
- string_format:基于 sprintf 的格式化
- default:为空或空串时返回默认值
- date_format:日期格式化(strftime 语义;PHP 8.1+ 走 date 映射)
-
返回值类型
- 字符串类修饰器返回 string
- 计数类返回 int
- default 返回 mixed(输入或默认值)
- date_format 返回 string|null(无效输入时可能返回 null)
-
复杂度与性能
- 多数为 O(n) 字符串扫描(n 为字符串长度)
- 正则表达式操作(如 strip、count_words)在长文本上开销较高,建议在大列表渲染中谨慎使用
- UTF-8 安全实现会进行额外字节级判断,避免 mbstring 缺失导致的问题
章节来源
- StandardFilters.php:36-63
- StandardFilters.php:65-425
- StandardFilters.php:427-563
日期时间函数(date_format)
- 语法:{$time|date_format:"%Y年%m月%d日"}
- 参数说明
- 第一个参数:时间戳、日期字符串或 14 位数字时间(YYYYMMDDHHmmss)
- 第二个参数:strftime 风格格式串
- 第三个参数:当输入为空时的默认日期
- 行为
- 空输入且未提供默认值时返回 null
- PHP 8.1+ 使用 date() 映射 strftime 占位符,保证跨版本一致
- Windows 平台对部分占位符做兼容替换
- 返回值:string|null
章节来源
- StandardFilters.php:192-229
- StandardFilters.php:507-563
URL 生成函数({url} 标签)
- 语法:{url link="模块.动作" params=["key"=>"val"] page=2 options=[] nofilter}
- 属性说明
- link:必填,路由标识(点分命名)
- params:可选,附加参数数组
- page:可选,页码
- options:可选,URL 选项(如是否带域名、协议等)
- nofilter:可选,关闭全局 HTML 转义(裸词 or 属性形态)
- 行为
- 编译为 route() 调用,最终由 UrlBuilder 生成完整 URL
- 支持 inline 键值对与 params 合并
- 全局开启 HTML 转义时,URL 输出会被 htmlspecialchars 包裹,除非使用 nofilter
- 返回值:string(完整 URL)
flowchart TD
Start(["进入 {url}"]) --> Parse["解析属性与参数"]
Parse --> CheckLink{"link 是否为空?"}
CheckLink --> |是| Err["抛出语法错误: missing 'link' attribute"]
CheckLink --> |否| Merge["合并 params 与 inline 键值对"]
Merge --> Route["调用 route(link, params, options)"]
Route --> Escape{"全局转义开启且未 nofilter?"}
Escape --> |是| Html["htmlspecialchars 包裹"]
Escape --> |否| Raw["直接输出"]
Html --> End(["返回 URL"])
Raw --> End
图表来源
- UrlTagCompiler.php:34-84
- UrlTagCompiler.php:86-151
- UrlBuilder.php:26-94
章节来源
- UrlTagCompiler.php:25-84
- UrlTagCompiler.php:86-151
- UrlBuilder.php:26-94
输出与转义({$x} 与 nofilter)
- 变量输出:{$x} 或三元表达式 {$a ? x : y}
- 全局转义:可通过模板引擎配置开启全局 HTML 转义
- nofilter:在输出或 URL 标签中使用 nofilter 可跳过转义
- 执行顺序:先计算表达式与修饰器,再根据上下文决定是否转义
章节来源
- EchoTagCompiler.php:26-45
- DouView.php:118-130
- UrlTagCompiler.php:70-84
依赖关系分析
- 模板引擎依赖编译器与缓存机制
- 修饰器通过注册表集中管理,便于扩展与维护
- URL 构建依赖路由系统与站点配置,确保伪静态与短地址策略一致
graph LR
DV["DouView"] --> DC["DouViewCompiler"]
DC --> TR["TagCompilerRegistry"]
TR --> UT["UrlTagCompiler"]
DV --> FR["FilterRegistry"]
FR --> SF["StandardFilters"]
UT --> UB["UrlBuilder"]
图表来源
- DouView.php:198-230
- DouViewCompiler.php:172-204
- FilterRegistry.php:21-63
- UrlTagCompiler.php:34-84
- UrlBuilder.php:26-94
章节来源
- DouViewCompiler.php:172-204
- FilterRegistry.php:21-63
- UrlTagCompiler.php:34-84
性能与执行优先级
- 编译期优先:模板编译一次,产物缓存,减少重复解析
- 运行期修饰器:按声明顺序从左到右执行,避免嵌套过深
- 正则与 UTF-8 处理:在大数据量下注意性能,必要时在控制器层预处理
- URL 构建:尽量复用具名路由与参数,避免复杂拼接
常见业务场景与组合示例
- 商品列表页标题与描述
- 使用 truncate 限制标题长度,cat 拼接站点名
- 使用 default 提供空字段回退
- 使用 date_format 显示更新时间
- 文章详情页 SEO
- 使用 escape(html) 防止 XSS
- 使用 wordwrap 控制摘要长度
- 使用 {url} 生成分享链接,page 用于分页
- 订单状态展示
- 使用 capitalize 首字母大写
- 使用 replace 替换敏感信息(如手机号脱敏)
- 使用 string_format 格式化金额(两位小数)
错误处理与异常
- 缺少必要属性:{url} 未提供 link 将触发语法错误提示
- 非法模板路径:模板解析拒绝包含 .. 或空字符的路径,防止越界访问
- 空值与默认值:date_format 空输入且无默认值返回 null;default 提供回退
- 全局转义:开启后 URL 输出会被转义,需配合 nofilter 使用
- 时区与格式:Windows 平台对部分 strftime 占位符有兼容处理;PHP 8.1+ 使用 date 映射
章节来源
- UrlTagCompiler.php:41-43
- DouView.php:238-274
- StandardFilters.php:192-229
- StandardFilters.php:507-563
结论
DouPHP 模板内置函数以“修饰器 + 标签”的方式提供强大的数据与 URL 处理能力。通过统一的注册表与编译器,既保证了易用性,又兼顾了性能与安全。建议在模板中合理使用修饰器与 {url} 标签,结合全局转义与 nofilter 控制,确保输出正确与安全。对于大数据量场景,建议在控制器层进行预处理,以减少模板层的计算压力。