文档目录
内置函数

简介

本文件为 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:换行转 &lt;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 控制,确保输出正确与安全。对于大数据量场景,建议在控制器层进行预处理,以减少模板层的计算压力。

添加日期:2026-10-05