☰
Grav 2.x 版本演进深度解读:从 CHANGELOG 透视性能优化、安全加固与 AI 就绪能力
2026/10/4 1:40:35 网站建设 项目流程
  • 后端

【免费下载链接】grav

Modern, Crazy Fast, Ridiculously Easy and Amazingly Powerful Flat-File CMS powered by PHP, Markdown, Twig, and Symfony

项目地址:https://gitcode.com/gh_mirrors/gr/grav
点击查看免费下载

导读

本文以仓库根目录的 CHANGELOG.md(5322 行、横跨 v1.7.0 至 v2.2.4 的完整发布史)为核心脉络,系统梳理 Grav 2.x 系列在页面缓存与索引性能、Twig 内容沙箱与上传安全、面向 AI/Agent 的 Markdown 输出、多站点环境隔离、媒体图像与调度器等关键方向上的演进。读完本文,你将掌握 Grav 2.x 各版本新增的核心配置项(如pages.lazy_index、session.lazy、pages.frontmatter.native_yaml、twig_content.*与twig_sandbox.*)、关键命令行操作(如bin/grav scheduler --catch-up、bin/gpm selfupgrade),并能依据仓库内配置与源码文件(system/config/security.yaml、composer.json、webserver-configs 等)快速定位每个特性在真实代码中的落点,为升级评估、安全审计与二次开发提供可检索、可引用的依据。


一、CHANGELOG 全景:从 v1.7 到 v2.2 的版本脉络

Grav 的 CHANGELOG 采用倒序时间线组织,顶部是最新版本# v2.2.4(09/30/2026),向下依次回溯 v2.2、v2.1、v2.0 及 1.x 维护分支。每个版本内部按三类条目组织:

条目标记含义典型内容
[](#new)新功能新配置项、新 Twig 函数/过滤器、新 CLI 命令
[](#improved)改进/优化性能优化、依赖升级、行为调整
[](#bugfix)缺陷修复含[security]前缀的安全修复与 CVE/GHSA 编号

近期版本的发布节奏呈现"高频小版本迭代 + 大版本集中攻坚"的特点:v2.0.0 于 06/20/2026 发布稳定版,随后 2.0.x 以近乎每周一个补丁的速度推进,2.1.0 在 09/11/2026 引入"Markdown 输出"重大能力,2.2.x 则集中做性能与多站点加固。1.7 分支(如 v1.7.53)在 2.0 开发期间仍持续同步安全修复(如user/accounts等敏感目录的访问封锁),体现了安全补丁向下游维护分支的回流策略。

与源码对照,composer.json 显示当前主干要求PHP^8.3,依赖 Symfon y Cache/Yaml/Console 等组件^7.0、Twig3.x-dev(Grav 维护的 fork)、Monolog^3.0、rockettheme/toolbox ^2.0、wikimedia/minify ^2.11(v2.2.0 引入的现代 CSS 压缩器)以及rhukster/dom-sanitizer ^1.0.14——这些依赖版本本身即可佐证 CHANGELOG 中"更新 vendor 库"条目的实际内容。


二、性能与缓存:v2.2.0 开启的大规模优化

v2.2.0(09/24/2026)是 CHANGELOG 中性能改进最密集的一个版本,其核心思路可归纳为四类。

2.1 页面缓存:从"全量重建"到"按需增量"

  • 重建不再为每页写编译文件:清缓存后的首个请求明显更快,因为页面缓存重建不再生成全量编译文件。
  • OPcache 不再被页面缓存挤爆:重建过程不再把每页编译文件全部装入 OPcache,避免大站点把 Grav 其余缓存代码挤出内存。
  • 复用上次的页头(header):只编辑一个页面时,重建仍保持原来的速度。
  • 变更检查只扫已知页面:不再全量扫描pages文件夹;配合cache.check.interval(v2.0.7 引入,默认复用扫描结果数秒)可显著降低大站点每个请求的 stat 开销。
  • 单一请求负责重建,其余等待复用:只有一次请求执行重建,其他请求复用其结果,避免"缓存雪崩"式并发重建。
  • 保存/删除页面即时标记变更:通过 Grav 保存页面后,下一个请求即更新页面缓存;插件可调用Pages::markChanged()达到同样效果,且变更通知存放在独立小文件中,命令行保存与 Web 请求即使使用不同缓存驱动也能互相感知。

2.2 懒加载索引:pages.lazy_index从实验到默认auto

CHANGELOG 对页面索引的演进记录得非常完整:

  • v2.0.7:引入实验性pages.lazy_index: true,页面、路由、子列表、排序与分类法映射按需从每页索引加载,取代"一次性反序列化大缓存块"的做法。官方记录了一个可复验的测试数据:2000 页的测试站点渲染速度与 2 页站点相当,内存仅为四分之一(SQLite 可用时支撑索引,纯 PHP 回退)。
  • v2.0.7 同期:页面集合过滤器(visible、routable、published、module)改读索引中记录的菜单标志;500 篇博客在 Quark 主题下,单次页面视图构建的页面数从 507 降至 7。
  • v2.2.0:pages.lazy_index默认值改为auto——站点页面数达到 1000 或以上时自动使用页面索引,小站点继续用经典页面缓存,实现"无需任何配置即可提速"。

2.3 配置与渲染热路径

  • pages.frontmatter.native_yaml(v2.2.0,默认关闭):服务器装有 YAML 扩展时用其读取页面前置数据,速度更快;默认关闭是因为扩展对未加引号的日期和yes/no的解析与 PHP 实现不同。
  • 翻译按语言懒加载:清缓存后的首个请求不再读取所有语言文件;编辑某个语言文件时只重建该语言。
  • 配置与翻译缓存请求结束后再入 OPcache:不阻塞当前请求。
  • session.lazy(v2.2.0,默认关闭):仅当访问者确实需要会话时才启动会话,匿名页面可无会话 Cookie 输出,从而可被代理/CDN 缓存。
  • cache_modules: true(v2.2.0):模块页可缓存其模块输出;自带 Twig、含表单、已登录访客与表单提交始终实时渲染。
  • CSS 压缩改用 wikimedia/minify:理解现代 CSS,官方记录在真实样式表上快约 15–25 倍;配套修复包括calc()在@media/@supports/@container内保留空格、未闭合引号样式表回退为不压缩等(v2.2.0、v2.1.10)。
  • 页面 ETag 使用更快的哈希(v2.2.0)。

2.4 编译缓存原子写入

v2.1.6 修复了繁忙站点在安装/清缓存后刷屏Corrupt compiled cache警告的问题:编译文件先写到目标旁再 rename 覆盖,读者只会看到完整文件;无法写入时按缓存未命中处理而非服务器错误。该行为与 src/Grav/Common/File/CompiledFile.php 及 system/config/system.yaml 中的缓存配置直接相关。


三、安全防线:Twig 沙箱、XSS 与上传防护

安全是 CHANGELOG 中占比最大的主题,尤其集中在 2.0.x 补丁期。其演进主线是:把"渲染期检查"逐步前移到"保存期检查",并为编辑器编写的 Twig 建立以允许列表为核心的沙箱。

3.1 Twig 内容沙箱:三层门控与允许/拒绝列表

system/config/security.yaml 的注释是理解这套机制的第一手资料,它明确定义了按顺序求值的三层门控:

  1. twig_content.process_enabled(主闸门,v2.0.19 起默认开启):为false时页面内容中的 Twig 完全不解析,process: { twig: true }与system.pages.frontmatter.process_twig均被忽略;同时为process.twig提供每页默认值。
  2. twig_sandbox.enabled:闸门开启时限制页面内容 Twig 可做的事(标签/过滤器/函数/方法/属性允许列表)。违规软失败:页面其余部分正常渲染,访客看到占位符,管理员可从 logs 的security.log定位(logs/security.log自 v2.0.0-beta.2 起记录每次被拦截的 Twig 表达式、页面路由与修改建议)。
  3. twig_sandbox.config_denied_paths:沙箱开启且twig_content.config_access为真时,对configTwig 变量做子树脱敏。

当前配置文件的默认值(与 CHANGELOG 中 2026-08-12 的"安全配置审计"对应):

twig_content: process_enabled: true # 主闸门,自 2.0.19 起默认开启 editor_enabled: false # 仅拥有 admin.pages_twig 权限的用户可在编辑器切换 process: twig config_access: false # 沙箱渲染中 config 变量为空 twig_sandbox: enabled: true allowed_tags: [] # 以下均为"叠加式"扩充,默认策略内置在代码中 allowed_filters: [] allowed_functions: [] allowed_methods: [] allowed_properties: [] denied_tags: [] # 显式收紧,denied_* 优先于默认值与 allowed_* / 插件追加 denied_filters: [] denied_functions: [] denied_methods: [] denied_properties: [] config_denied_paths: [] # 追加脱敏路径(内置默认含 plugins/streams/security 等)

关键设计要点(v2.2.2 起):允许列表默认值内置在代码(Grav\Common\Twig\Sandbox\SandboxDefaults,见 src/Grav/Common/Twig/Sandbox)中,security.yaml只记录站点自己的扩充。原因在注释中说明得很清楚:Grav 对叶子列表采用替换式合并,站点若复制整张列表去微调,会"冻结"该列表、使其错过后续核心安全收紧;因此当前 keys 纯为叠加,要收紧需在denied_*下点名。

从 CHANGELOG 可以看到这条防线的历史闭环:v2.0.0-rc.4 让内容 Twig默认关闭并在迁移时自动检测;v2.0.19 改为默认开启并内置长允许列表;v2.2.0 修复"只追加条目导致date、max、batch等被误拦"的合并缺陷;贯穿 2.0.x 的多次 GHSA 修复(如通过array/print_r/json_encode/string过滤器转储配置、evaluate_twig绕过、map/filter/reduce/sort/find回调执行任意 PHP 等)最终收敛为上述"允许列表 + 拒绝列表 + 路径脱敏"的三段式策略。

3.2 内容 XSS 检查:从渲染期到保存期

  • v2.0.7 起,"渲染期扫描渲染结果"被废弃——检查前移到保存时,信任的插件/短代码输出(如 embed、表单、图标)不再被误伤;onXssTrustedMarkup事件(v2.0.4)允许插件豁免自有标记。
  • 检测器本身持续加固:事件处理器正则支持无引号属性(<img onerror=alert(1)>)、带引号属性值内的>、CSS 转义续行、javascript:后带空格等变体(对应 src/Grav/Common/Security.php 与 tests/unit/Grav/Security/DetectXssTest.php);同时修复误报(匈牙利语mondata:、metadata:、<option>/<select>、caption/button/section等)。
  • v2.0.1 增加渲染输出再检查:如{{ "on" ~ "error" }}这类运行期拼装的载荷也会在输出后被拦截。

3.3 上传、图像与文件系统

  • 危险扩展名:默认列表历经多次扩充(v2.0.0-beta.4 与 v1.7.52 加入md/yaml/yml/json/twig/ini;v2.0.15 加入xhtml/xht/svgz/php7/php8/pht/phtm/phps);v2.1.10 起任何位置的危险扩展名都被拒绝(evil.php.jpg不再能借助AddHandler运行),且 PHP 可执行扩展即使被站点配置移除也始终视为危险。
  • 上传文件名:v2.0.13 起禁止<、>、";v2.1.10 起PUT/PATCH上传剥离文件名中的目录路径(与POST行为一致)。
  • 图像变换:URL 查询参数式变换(?resize=2000,2000)自 v1.7.53/v2.0.0-rc.8 起默认关闭,开启时受可配置总像素上限约束(CWE-400);v2.1.7 起在 GD/Imagick 解码之前即拒绝超限源图;v2.2.2 起按每次实际产出的图像核算像素(含一维、百分比与 zoomCrop)。
  • 水印:编辑器提供的水印路径被限制在站点媒体内(v2.0.11,防止?watermark=../secret.png式穿越);v2.1.10 修复水印在 resize/crop/retina 产物上的定位。
  • read_file():v2.0.0-rc.9 拒绝../穿越与 NUL 字节;v2.0.0-rc.2 引入流、扩展名与文件大小三重允许列表(security.read_file.*);system/config/security.yaml 中可见其约束:仅接受 Grav 流 URI(如theme://foo.md),解析后的 realpath 必须落在流的根目录内,从机制上免疫编码式..。
  • DOM 消毒器持续升级:1.0.13(CSS 注释隐藏危险值、image-set())→ 1.0.14(@import式外链隐藏)→ 1.0.18(反斜杠-换行续行隐藏外部资源引用),对应 composer.json 中rhukster/dom-sanitizer的约束版本。

3.4 Web 服务器配置与.htaccess加固

CHANGELOG 反复出现"每份内置服务器配置同步加固"的条目,落点是仓库的 webserver-configs 目录(htaccess.txt、nginx.conf、Caddyfile、lighttpd.conf、web.config):

  • 敏感目录封锁:v2.0.0-rc.9 起user/accounts、user/config、user/data、user/env在所有内置配置中被整体封锁;每份配置内还附带 deny-all 的.htaccess,即使站点根.htaccess被定制也能兜底。
  • user/防护的演进:v2.0.19 新增的user/.htaccess曾因使用受限AllowOverride主机不允许的指令而把站点整目录搞挂(v2.1.4 用各主机都允许的等价指令重写;v2.2.1 彻底去掉 mod_rewrite);v2.1.6 将规则下推到user/下每个子目录并优先执行,插件/主题无法再通过自带.htaccess豁免自身目录(v2.0.19/2.1.6 多次交锋);user/data则以"媒体白名单"方式放行图片/字体/CSS/JS 而上传的 YAML/JSON 数据保持封锁(v2.0.4/v2.0.5/v2.1.5)。
  • 脚本执行阻断:v2.1.10 起images/与assets/目录禁止执行 PHP 及其他脚本;v2.1.7/v2.1.8 阻断tmp/(含临时包下载);v2.2.2 起文件类型规则在文件名后带路径时同样生效。
  • Caddyfile 曾完全失效:v2.0.15 记录了一个重要教训——旧规则是 nginx 风格正则,Caddy 按字面路径匹配永不命中,导致敏感目录直接可下载;修复后改用path_regexpmatcher 直接403并置于route块内先于 catch-all rewrite 执行。凡手工复制过这些配置的运维者都必须更新线上配置(CHANGELOG 在多处明确提醒,且升级器只自动修补.htaccess,nginx/Caddy/lighttpd/IIS 需手工同步)。
  • 机器人协议:v2.1.9 修复robots.txt误拦管道化 CSS/JS(移除Disallow: /assets/,规则以/开头并兼容查询串、显式放行system/与user/plugins/下资源);升级不会替换robots.txt,存量站点需手工应用。

四、AI/Agent 就绪:v2.1.0 的 Markdown 输出能力

v2.1.0(09/11/2026)引入的Markdown Output是 CHANGELOG 中面向 AI 生态的标志性新功能,描述极为详细,值得完整保留:

  • 任意页面可读为 Markdown:在任意页面 URL 后加.md,或发送Accept: text/markdown请求头,Grav 即返回"以主题渲染后的页面缩减到主内容区"再转回的 Markdown——博客列表、商店、产品页等模板构建的内容保持原样;短代码、内容 Twig、模块页、解析后的图片/链接路径全部保留,而导航、侧栏、页脚被剔除。
  • 文档级结构:每份 Markdown 文档以 YAML 块开头(title、URL、date、description、taxonomy),以父/邻/子页面的.mdURL 链接收尾,Agent 可不离开 Markdown 走完整个站点。
  • HTTP 语义:HTML 响应携带Link头与<link rel="alternate" type="text/markdown">指向 Markdown 版;Markdown 响应携带X-Markdown-Tokens头给出估算 token 数(对齐 Cloudflare 的 Markdown for Agents 约定)。
  • 配置开关:整套能力及其各部件可在Configuration → System → Content的 Markdown Output 设置中独立关闭。
  • 模板定制:主题可用default.md.twig或<template>.md.twig覆盖布局(仓库已有 templates/default.md.twig),并使用新 Twig 函数markdown_output()、markdown_frontmatter()、markdown_body()、markdown_links()、markdown_url()与html_to_markdown过滤器。
  • @gravTwig 命名空间:Grav 自带模板可通过@grav命名空间引用(如@grav/partials/metadata.html.twig,对应 templates/partials/metadata.html.twig),主题无需整份复制文件即可追加一行。
  • 首页与其他格式:首页可按/index.md、/index.rss、/index.json等请求(避开/.md被服务器当作隐藏文件的坑);page.url()新增第五个参数指定输出格式,如page.url(true, false, true, false, 'rss')。
  • 媒体全 URL:媒体url()新增第二参数拼接 scheme 与主机(如 Open Graph/Pinterest/feed 场景的page.media['photo.jpg'].url(true, true)),在子目录安装、custom_base_url与pages.media_route_urls场景下与page.url(true)行为一致。
  • 输出格式 MIME 可配:在 user/config/media.yaml 设media.types.rss.mime即可改变 RSS 输出 Content-Type(atom/xml/json/md同理),便于 XSLT 美化 feed。
  • 配套语义修复:对.md请求的重定向指向目标的.md版;开启 Markdown 输出后无扩展名 URL 发送Vary: Accept,避免共享缓存把 HTML 给 Agent 或把 Markdown 给浏览器;Apache/lighttpd 配置仅当.md指向真实文件时才拦截(页面路由以.md结尾可正常到达 Grav,user/pages下的源文件仍被封锁),升级器会修补存量.htaccess中的原始行。

同时 v2.1.0 新增Flex Render Hints调试器设置(默认关闭):为每个渲染的 Flex 对象/集合包裹命名 HTML 注释,便于在页面标记中定位区块来源;该标记只出现在 HTML 页面且是合法注释(此前误写破坏 RSS/Atom/XML/Markdown 输出的问题即由此转为 opt-in 修复)。


五、多站点与环境隔离

CHANGELOG 记录了完整的环境机制演进:

  • user/env/<host>/多站点:v1.7.0-rc.18 起支持将每个站点/环境置于user/env下;v2.2.4 修复多站点在user/env/<host>/下重新加载主题/插件/媒体文件的问题,并把config/、accounts/、data/在 env 内的保护与user/对齐;nginx/Caddy/lighttpd/IIS 需手工从 webserver-configs 复制新规则。
  • 调度器环境感知:v2.2.2 修复bin/grav scheduler --env <host>启动的站点,其任务不带user/env/<host>/config设置运行的问题;v2.0.20 修复 cron 生成的命令未带环境名导致自定义任务静默失败的问题。
  • 环境变量体系:v2.0.0-rc.6 起原生读取站点根.env文件(不再需要 DotEnv 插件),GRAV_ENVIRONMENT、GRAV_CONFIG__*覆盖可用;v2.0.0-rc.9 新增GRAV_ENV_PATH把.env放到 Web 根之外以保护 API 密钥;v2.0.23 修复GRAV_CONFIG__覆盖设为true/false时被当成字符串的问题。
  • v2.0.0-rc.4 的防护:保存主题/插件/系统配置时不再静默创建不存在的user/env/<host>/文件夹(防止代理怪癖导致的主机名漂移)。

六、媒体与图像处理

  • pages.media_route_urls(v2.0.25 新增,默认关闭):页面媒体按页面路由而非磁盘路径链接,使插件可为媒体请求套用页面的access规则;开启后配合的"拒绝直接访问user/pages"规则才变得安全。后续修复包括:含空格/重音字符的文件名不再 404(v2.2.2)、Markdown 内图片(含跨页与 lightbox)经页面路由链接(v2.1.0)、与images.cls.auto_sizes同开时不再getimagesize()报错。
  • 图片行为修复:同一张图在 Markdown 中多次使用时不再串用前次引用的查询参数/锚点/样式,并保留裁剪后的 retinasrcset(v2.2.2,#3567/#4333);format()/quality()现在作用于全部 srcset 替代品,含既存与后建的衍生图(v2.1.7);AVIF 在 Imagick 下真正尊重质量设置(v2.1.3)。
  • system.images.progressive_jpeg(v2.0.24 新增,默认开启):控制缩放/缓存 JPEG 是否存为渐进式(恢复自 2014 年起的默认行为,1.4.6 时静默失效)。
  • system.images.defaults修复:v2.0.24 恢复resize等默认滤镜与loading: lazy在link开启时留在 img 上;v2.0.24 修复媒体文件自身media.yaml设置被打开瞬间覆盖的问题。
  • 图像缓存保留:v2.1.0 修复升级执行全量清缓存时忽略cache.clear_images_by_default导致缩略图全部再生的缺陷;bin/grav cache --images-only仍可按需清除。
  • CSS 管道:v2.1.11/v2.1.12 修复@import样式表被管道化/压缩时整块移位、url()非文件路径(about:blank、blob:)被改写、URL(...)大小写与括号内空格、SVG 渐变fill: url(#...)失效等问题(src/Grav/Common/Assets/Pipeline.php 相关)。

七、调度器、备份与 GPM

7.1 调度器(Scheduler)

调度器自 v1.6.0 引入、v1.7.49 重构后持续增强:

  • 补跑错过的任务:bin/grav scheduler --catch-up(v2.0.22)运行已错过计划时间的任务,适合没有 cron 条目的站点。
  • 触发识别更智能:v2.0.18 起按"每个任务在自己的计划时间是否运行过"判断,而非要求最近两分钟内有一次运行——稀疏 crontab、webhook、Windows 计划任务都算数。
  • 单任务强制运行:bin/grav scheduler -r <job-id>(v1.7.0-rc.2)并按任务记录运行历史(v2.0.22);-j/-d对插件注册任务与从未运行的任务不再报错。
  • 并发与队列:v1.7.49 引入 webhook 触发、并发任务、任务队列与日志。
  • 健壮性:proc_open被禁用时不整体失败(v2.0.18);任务锁存放在站点内而非共享系统临时目录(v2.0.16,GHSA-q8w8-6cq5-j4h2);队列反序列化仅允许Job类(v2.0.0-rc.6,配合 HMAC 完整性校验);注册无计划时间的任务不再报错(v2.0.22)。
  • 相关实现可查 src/Grav/Scheduler/Scheduler.php、src/Grav/Scheduler/SchedulerController.php 与 CLI 入口 src/Grav/Console/Cli/SchedulerCommand.php。

7.2 备份

  • v1.6.0 引入多配置文件与调度器集成;v2.0.13 将备份档案位置限定在站点文件夹内(防外部目录入包);v2.0.7 起备份档案按块流式输出,不再受 PHP 内存限制;v2.0.7 让备份配置在调度器中始终可见并可用开关启停。

7.3 GPM 与升级

  • 大版本识别:v2.1.1/v2.1.2 修复 2.0 → 2.1 升级被误判为"新主版本"而要求全插件声明兼容的问题;bin/gpm selfupgrade现在只在真正的新主版本(如 2.0)时提示并指向迁移指南。
  • 许可证:v2.1.5 支持premium.license_product——一份许可证覆盖多个包(如商店插件及其支付提供商);v2.1.0 接受其他商店(如 KahunaCartKC-XXXX-...)发行的密钥;下载被拒时打印商店原因与续费入口。
  • 升级健壮性:v2.2.2 修复 Windows(如 Laragon)下从 Admin 升级误删index.php;v2.0.4 修复共享文件夹(VirtualBox)下bin目录无法删除的问题(原地覆盖);v2.0.3/v2.0.2 输出具体失败文件与属主;v1.8.0-beta.9 起核心自带 staging/validation/rollback 的 safe upgrade。
  • cache-cleanupCLI(v1.7.51)只清理过期缓存项;bin/grav clean的发布裁剪清单随 2.0 依赖变化持续更新。

八、表单、Blueprint 与数据验证

  • 数字步长(step)验证:v2.1.6 把步长检查从二进制浮点改为"按输入的数字串"计算,0.0000001步长下纬度81.96不再被误拒;any/0/非数字步长不再触发除零致命错误,一律按"无步长"处理(与浏览器一致)。
  • 服务端长度校验:v2.0.22 让minlength/maxlength在提交时真正生效(此前仅写入 HTML 属性);多行字段上限调整为max: 0取消限制;超长/超短字段报错时给出提交值与限制值。
  • 页面内容长度:v2.0.22 解除 65,536 字符的页面正文上限。
  • Blueprint 列表字段:v2.2.4 修复"只含elements字段的列表"保存报错,且元素内字段归属各列表项、不再与蓝图顶层同名字段冲突。
  • 动态数据调用防护:贯穿 v2.0.7→v2.0.15 的 GHSA 系列把"数据提供器指向危险函数/Class::method"的多形态绕过全部封死,页面 frontmatter 表单(v2.2.2)与 Flex 表单合并(v2.2.2)同样过 allowed-callable 检查。
  • 日期验证:v2.1.3 修复未加引号date: 2022-01-06被 YAML 解析成时间戳后拒绝保存(Admin Next 与 API);v2.0.25 修复未加引号日期被误读成公元 7200 年。
  • Blueprint 扩展生态:compatibility:支持(v1.7.51)、grav依赖代际键(v2.0.24:- { name: form, version: '>=9.1.0', grav: '2.0' })、authorize-*@:/flex-ignore@动态属性(v1.7.36)等均有记录。
  • 相关验证实现与测试可查 src/Grav/Common/Data/Validation.php 与 tests/unit/Grav/Data 下的ValidationNumberTest.php、ValidationLengthTest.php、ListElementsValidationTest.php等。

九、升级与运维须知(按 CHANGELOG 整理)

以下操作在 CHANGELOG 中被明确标注为需要人工执行,升级前应逐条核对:

事项版本说明
复制新.htaccess规则块v2.2.2/v2.2.4Admin 静态资源一年缓存、env 目录保护等需从 webserver-configs/htaccess.txt 手工并入存量.htaccess
更新 nginx/Caddy/lighttpd/IIS 配置v2.1.10/v2.1.7/v2.0.0-rc.9 等升级器只自动修补.htaccess,其余服务器必须手工同步(含敏感目录封锁、隐藏文件与.well-known例外、tmp/阻断)
手工应用robots.txt变更v2.1.9升级永不替换robots.txt
Caddyfile 规则v2.0.15旧规则完全不生效,必须替换为path_regexp版
会话 Cookie 更名v2.0.22system.session.name含大写/下划线/首尾连字符的站点,升级后 Cookie 名变化,用户将登出一次
security.yaml允许列表v2.2.0此前站点若通过复制列表"收紧",升级会转为显式denied_*条目,策略不变
图像变换开关v1.7.53/v2.0.0-rc.8?resize=默认关闭,需显式开启并设置像素上限

此外,v2.0.19 起"Twig in Content"在新装站点默认开启;2.0 分支对旧security.twig_filter.*正则预过滤已退役(v2.0.0-beta.3),Twig 沙箱成为唯一的 SSTI 防护层——关闭它将移除对编辑器内容唯一的保护。


十、源码与测试佐证:如何把 CHANGELOG 落回代码

CHANGELOG 的每类条目都能在仓库中找到对应落点,便于读者自证:

  • 安全策略:system/config/security.yaml(三层门控、允许/拒绝列表、read_file约束)、system/blueprints/config/security.yaml(Admin 表单)、src/Grav/Common/Twig/Sandbox(内置默认策略SandboxDefaults)。
  • 测试覆盖:tests/unit/Grav/Security 下的DetectXssTest.php、DetectXssFailClosedTest.php、MediaResizeSecurityTest.php、MediaStyleSecurityTest.php、MediaAttributeSecurityTest.php、DynamicDataCallGuardTest.php对应 XSS 与动态数据防护条目;tests/unit/Grav/Data/ValidationNumberTest.php 对应 step 验证修复;tests/unit/Grav/Scheduler 对应调度器行为。
  • 性能与缓存:system/config/system.yaml(pages.lazy_index、cache.check.interval、session.lazy、images.cache_perms等默认值)、src/Grav/Common/Cache 与 src/Grav/Cache.php。
  • 媒体:src/Grav/Common/Page/Media.php、src/Grav/Common/Media/MediaRouteUrls.php 及 tests/unit/Grav/Page/Medium 的 8 个测试文件。
  • 服务器配置:webserver-configs/htaccess.txt、webserver-configs/nginx.conf、webserver-configs/Caddyfile、webserver-configs/lighttpd.conf、webserver-configs/web.config。
  • 依赖基线:composer.json(PHP 8.3、Symfony 7、wikimedia/minify、dom-sanitizer 版本区间)。

结语

从 CHANGELOG 的演进脉络可以清晰地看到 Grav 2.x 的三个战略重心:用懒加载与增量策略把大站点的缓存成本压平(lazy_index: auto、按需翻译、OPcache 后置编译)、把编辑器内容的安全防线从"渲染期拦截"推进到"保存期校验 + 沙箱允许列表"的纵深防御(twig_content/twig_sandbox三层门控、denied_*收紧、媒体与上传多重限制)、以及面向 AI 生态输出结构化 Markdown(Accept: text/markdown、.mdURL、token 估算与导航链接闭环)。对运维者而言,本文第九节的"人工操作清单"是每次升级前最值得对照的检查表;对开发者而言,CHANGELOG.md 与上节列出的源码/测试路径相互印证,构成了一条可完整回溯的版本演进证据链。

  • 后端

【免费下载链接】grav

Modern, Crazy Fast, Ridiculously Easy and Amazingly Powerful Flat-File CMS powered by PHP, Markdown, Twig, and Symfony

项目地址:https://gitcode.com/gh_mirrors/gr/grav
点击查看免费下载
上一篇:【免费下载】 Avidemux:一款强大且易用的视频处理工具
下一篇:CC Switch 完整用户手册:从基础配置到高级功能详解

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询