最近把 Teanary 的 V1.2.1 版本正式推送出去了这个版本对我来说多少有点特殊因为它是 Teanary 最后一个基于 FilamentPHP 的稳定版本。以后 Teanary 的迭代方向会有变化所以这一版既是给老用户的一个交代也算是我自己在这条技术路线上的一次总结。如果你正好在用 FilamentPHP 做后台管理类项目或者正在纠结要不要选它这篇文章里我把 V1.2.1 的发布内容、版本背后的取舍、以及这几年在 FilamentPHP 上踩过的坑都整理了一下希望对你有参考价值。1. Teanary V1.2.1 到底更新了什么1.1 基于 FilamentPHP 的资源模块重构Teanary 本质上是一个面向运营管理场景的后台系统核心功能包括内容管理、权限分配、数据看板和一些常规的审批流转。V1.2.1 这个版本最重要的一件事是把大量基于 Filament 的 Resource 做了重构重点解决的是资源列表在大数据量场景下的加载问题。之前用 Filament 的 Table Builder 时列表页在数据量到了五六万条以后响应开始变得明显迟钝。排查下来问题集中在两处一是默认的ModifyQueryUsing里叠加了太多闭包查询每渲染一次列表就会跑一堆额外的 count 统计二是部分列的格式化逻辑写在formatStateUsing里前端渲染时每一行都要重新执行开销非常大。V1.2.1 里把所有统计类查询统一挪到了Widget或者独立的聚合器里列表页只保留基础查询count类指标改为异步刷新。实测下来同样的数据配置页面首屏渲染时间从原来的 2.1 秒左右降到了 600 毫秒以内内存占用也有明显下降。1.2 表单状态同步与多步骤流程的问题修复Teanary 有一块业务是审核流最早是基于 Filament 的Wizard组件做多步骤表单。V1.2.1 修复了一个比较麻烦的状态同步 Bug具体表现是当审核人在第二步修改了某项数据之后回退到第一步之前填写的内容会丢失一部分原因是Wizard在步骤切换时会重新挂载 Livewire 组件而没有实现完整的state落盘。这个问题的根源在于 Filament 的Wizard虽然方便但它默认每个步骤的生命周期是独立管理的跨步骤的数据必须手动保存到data()里。之前写得太随意只保存了当前步骤的表单数据。V1.2.1 的做法是对整个Wizard做了一层统一的状态容器每次步骤切换时强制把所有步骤的字段快照存入隐藏字段再配合mountStep()回调做恢复。这个改动不复杂但效果很直接用户反馈里关于审核流程填了一半被清空的问题终于消停了。1.3 权限策略的动态刷新Teanary 前端部分用了 Filament 自带的Panel布局导航菜单和权限入口都是基于canView()来做的。之前的版本有个问题用户权限在后台被修改后登录状态的用户需要强制刷新浏览器才能看到新的菜单项因为 Livewire 组件挂载后canView()的结果被缓存住了不会主动感知权限变化。V1.2.1 在用户会话里增加了一个权限版本号机制每次权限变更都会让版本号递增前端通过轮询版本号来判断是否需要重组导航和路由表。这个体验优化看似不起眼但对后台系统来说很重要因为运营人员经常需要快速切换角色每次都要硬刷新真的很影响效率。2. 为什么这是“最后一个基于 FilamentPHP 的稳定版本”2.1 FilamentPHP 很快但业务逻辑开始“反向适配框架”很多人问我既然 FilamentPHP 这么适合做后台为什么不继续用了。坦白说FilamentPHP 本身不是什么问题问题是 Teanary 后续要做的功能和 Filament 的抽象模型开始出现了明显的方向性冲突。Filament 的设计哲学是“约定大于配置”它把常规的 CRUD、表单、表格、关系管理做成了高度抽象的组件。你只需要定义一个 Resource 类填一些 schema 数组就能得到一套能跑的标准后台。这在小规模、标准化程度高的管理端里体验非常爽开发速度极快。但 Teanary 后续规划里有一些高度定制化的交互界面比如流程设计器、拖拽式布局、实时协同编辑这些场景需要的是“无框架约束的组件级控制权”。在 Filament 里这些东西也能做但需要绕过框架的默认行为写大量的自定义 Livewire 组件去覆盖原有抽象本质上变成了“框架让你填空你却非要改试卷”。到 V1.2.1 这个阶段代码里已经有相当一部分自定义逻辑是在和 Filament 的默认行为做对抗比如覆写很多Table的查询、禁用默认的CreateAction再自己实现一个。这种感觉就像用装修公司的套餐精装房一开始省事但你想拆掉一堵承重墙做开放式厨房就得先和物业扯皮。2.2 上游依赖的演进压力另一个现实问题是 FilamentPHP 本身的迭代速度非常快社区也很活跃这本来是好事但对 Teanary 这种维护资源有限的项目来说反而成了压力。Filament 的大版本升级带有一定的破坏性变更尤其是从 V2 到 V3 那一次资源、表单、表格的内部 API 做了不少调整。虽然官方提供了升级工具但涉及自定义组件时还是要花不少精力去适配。Teanary 此前锁定在 Filament V3 这条线上V1.2.1 发布时同步验证了所有第三方插件的兼容性其中一个表单签名插件、一个地图选点插件都做过二次包壳升级成本确实在累积。长期来看如果一个业务系统的核心价值已经不在“标准 CRUD”上而 FILament 的版本演进又要求持续投入适配成本那就需要重新评估这个技术栈的杠杆效应了。Teanary 选择在 V1.2.1 做一个收尾是因为这里更适合画上分号而不是等到框架大版本变动时被迫硬切。2.3 迁移方向的初步判断后续 Teanary 计划把前端逐步迁到一套更自主可控的组件体系上后端继续走 Laravel API前端用轻型的独立前端框架承载复杂交互。这个思路并不是说 FilamentPHP 不好而是 Teanary 到了新阶段需要的不是“面板生成器”而是一个可以自由绘制的画布。有朋友问我会不会直接一步到位换成别的后台框架我的答案是不会刻意去找到一个 Filament 的替代品因为 Teanary 已经过了需要后台框架适配器的阶段。新架构更接近“前端工程 后端接口”的方式把业务实体、权限策略、数据结构继续留在 Laravel 侧用 API Resource 对外暴露前端只管专心做交互。这个方向对团队的技术要求会更高一点但长期维护的灵活性会更好。3. 从 V1.1 到 V1.2.1小版本迭代里的工程管理复盘3.1 双轨发布与反馈通道Teanary 从 V1.1 到 V1.2.1 的迭代周期差不多五个月。这个阶段我做得比较满意的一件事是双轨发布也就是每次发版前先把候选版本放到一个单独的更新通道里让一批愿意尝鲜的用户先跑两到三周稳定后再推全量。这个机制很有用因为很多问题只有在真实业务数据下才暴露得出来。比如 V1.2.0 候选版里有一个列表筛选器的排序问题开发环境怎么测都正常但到了生产环境因为数据里包含了大量空值字段排序结果就乱掉了。这种问题靠自测很难发现必须靠真实环境反馈双轨渠道帮我在全量发布前抓住了好几个类似的边界 case。3.2 兼容性测试清单的重要性到了 V1.2.1我整理了一份兼容性测试清单覆盖了部署环境相关的关键路径。Teanary 的典型部署环境是 PHP 8.2 MySQL 8.0但后来发现相当一部分用户跑在 PHP 8.1 或者 MariaDB 10.6 上所以清单里专门加了跨版本数据库的行为差异验证。这里有个具体的例子MySQL 8.0 默认utf8mb4_general_ci排序规则MariaDB 10.6 对某些 Unicode 字符的排序行为和它不一样当表单里包含生僻字时列表筛选和排序的结果会不同。V1.2.1 里专门针对这种情况调整了字段的排序规则确保在 MariaDB 下也能保持一致。这份清单现在也开源了后续就算 Teanary 换内核这套测试思路也还能继续用。3.3 最后版本的文档锁定由于 V1.2.1 是 FilamentPHP 路线的最后一个稳定版文档这块我做了特殊处理把所有和 Filament 相关的自定义组件的说明都单独集中到了一份“Legacy 附录”里包括每个自定义组件的基于 Filament V3 的适配说明、初始化参数、常见问题。这样之后新架构上线时老用户迁移数据也好二次开发也好都有一份明确的索引。这件事看起来琐碎但真的很重要。开源项目或者商业项目的维护者里最容易被忽略的就是旧版本的文档维护。版本一旦停更如果文档还散落在各处的更新日志里后面的接手者会非常痛苦。4. 如果你也在用 FilamentPHP选型判断与实用避坑清单4.1 谁适合选择 FilamentPHP谁可能需要再想想FilamentPHP 适合的场景非常清晰以标准 CRUD 为主的管理后台比如内容发布、用户管理、订单列表、报表展示要求快速交付、界面统一、交互标准。这类项目用 Filament开发效率是真的高一个 Resource 就能覆盖一整套对数据模型的操作界面官方文档也写得清晰社区有不少现成插件解决通用需求。但如果你很明确地知道自己要做高度非标的交互并且交互复杂度明显超出“列表 详情 编辑表单”这种范式那用 Filament 就要慎重了。不是说它不能做而是你需要花大量时间在“绕过框架默认行为”上。最后写出来的代码可能 70% 都是自定义的 Livewire 组件和 JS 交互Filament 本身的价值只剩下 UI 外框和导航管理这笔账不一定划算。4.2 生产环境容易踩的坑我在 Teanary 项目里用 FilamentPHP 踩过的坑挑几个典型的说说列表查询注入位置要小心。Filament 的Resource默认会在Table构建时执行查询如果你在getEloquentQuery()里做with()预加载又在列里做关联字段访问很容易引发 N1 查询。特别是关联关系中嵌套 out-of-scope 的条件时要留意查询有没有正确加载。表单dehydrated字段千万不要乱设。有些字段你只是想临时展示不想入库如果忘了设dehydrated(false)它照样会被写入数据模型这是个很容易漏掉的坑尤其常见于多选联动字段。多租户场景下注意Panel路由的参数传递。Filament 支持多租户但路由参数在不同租户间切换时如果panel-getId()依赖了租户上下文很容易出现面板加载混乱的问题。Teanary 早期在子域名切换时踩过一次这个坑后来是改成在中间件里统一绑定租户上下文才解决。4.3 什么时候应该考虑退出 Filament这个判断标准我个人觉得可以这样量化当你发现自己项目里“自定义 Livewire 组件 JS 交互”的代码量已经超过了 Filament 自动生成的资源代码量而且每次升级 Filament 版本都要处理多个自定义组件的兼容性问题那就要认真考虑退出的时间点了。“最后一个基于 FilamentPHP 的稳定版本”这个决定我并不是在某个文档里突然看到“不推荐”才做的而是因为 V1.2.1 开发过程中我发现对 Filament 默认行为的覆写已经触及了一些底层状态管理机制继续做的成本会指数级上升。与其硬撑不如规划一次有掌控的迁移。5. 给还在维护 FilamentPHP 项目的朋友一些升级建议5.1 再用 V1.2.1 也要做好安全与兼容层Teanary V1.2.1 虽然是这一技术路线上的收尾版本但它本身不是“阉割版”所有功能都是完整可用的我也会继续维护到后续新版本稳定之后再进入低维护期。这个版本在安全方面补了几个关键的依赖升级Laravel 与 Livewire 的安全性都同步到了当前可支持的范围。如果你是在老项目里继续用 FilamentPHP我的建议是不要停在某一个小版本上不动至少要跟随到该大版本的最近 patch。框架类项目的安全修复是会持续往最新小版本打的旧版本很容易成为漏洞靶子。Teanary V1.2.1 里也顺带做了一个依赖检查脚本每次部署都会检测 composer 依赖的已知安全漏洞这个思路推荐保留下来。5.2 ARM/Debian 环境的部署经验最近有个朋友把 Teanary V1.2.1 部署到了一台 ARM 架构的 Debian 系统上就是那种小型的 NAS 设备性能有限但胜在省电和安静。这里有几个坑想特别说一下PHP 扩展列表这套环境用的 PHP 8.2 是自编译的一开始漏掉了php8.2-mysql和php8.2-xml这两个扩展导致 Filament 的表单组件在渲染时直接 500。部署 ARM 设备前先把php -m的输出和 Filament 官方文档里的扩展要求对照一遍。Livewire 的 WebSocket 与异步问题Filament 的实时组件依赖 Livewire在低功耗 ARM 设备上性能会打折扣尤其是大量并发请求时。朋友那边做了一层缓存策略把 List 页面的查询结果缓存三到五分钟有效减轻了 CPU 压力。如果你的后台不是强实时性需求这个思路完全可以照抄。磁盘 I/O 敏感ARM 设备多半配的是 SD 卡或者机械硬盘数据库写入频繁时延迟会很明显。部署时建议把 MySQL 或 MariaDB 的数据目录放到一块 SSD 外接盘上同时把 session 和 cache 驱动改成 redis而不是默认的文件驱动体感能提升不少。5.3 数据迁移到新架构时要提前做好的准备如果你也和 Teanary 一样计划从一个 FilamentPHP 项目迁出我的建议是先在原项目里做好数据层面的规范化沉淀。具体来说把资源列表里的导出功能补齐确保所有核心数据都能完整导出整理权限表与导航菜单的元数据这些东西在新架构里大概率还要用只是表现形式变了用文档把现有表单的校验规则、联动逻辑记录清楚别等到迁移时再翻代码。Timing 上尽量选择一个功能和数据都相对稳定的节点作为最后版本。Teanary 选择 V1.2.1 就是这个原因业务功能没有半吊子数据模型都收敛了迁移的时候不需要处理历史遗留的脏数据。6. V1.2.1 发布后的维护计划与后续节奏V1.2.1 发布后我不会立刻冻结维护而是按三个层级来安排后续的事情一是安全维护期这个版本相关的安全补丁和依赖升级在接下来一段时间内仍会继续跟进确保老用户在迁移窗口期内不至于裸奔。二是文档与社区答疑期围绕 FilamentPHP 的遗留问题我会在社区继续保持回答把 Teanary 这几年里积攒的经验慢慢沉淀成文章和代码片段作为迁移前的参考。三是新架构的研发窗口期之后 Teanary 会转入新的技术路线这会是一个重新打磨的过程节奏会比之前慢一些但方向更清晰。如果你手头有项目在用 FilamentPHP又正好在犹豫要不要迁移那我给个不成熟的建议不一定要立刻放弃但一定要开始做技术债盘点。把那些被迫覆写框架默认行为的地方单独拉一个清单列出维护成本和升级风险等某个机制点出现时你动手的决定就会顺理成章。Teanary V1.2.1 在这个节点完成发布也是因为我意识到继续在 FilamentPHP 这一层做“自定义对抗”已经不是改变了框架而是在和自己的历史代码对抗。我个人这几年最深的体会是选框架不一定要选最强的但一定要选一条能长期顺畅走完的路。FilamentPHP 让我在 Teanary 早期快速跑通了大量业务模型这一点我不会否认但到了后期更重要的能力是知道什么时候停下来换一条更宽的路继续走。