Skip to content

Repository files navigation

Fairwell, Drupal and PHP

两个年代的盘桓,一个时代的终结

当我敲下"Fairwell, Drupal and PHP"这四个字的时候,没有人知道我到底有多悲伤。我想,也许就是悲伤逆流成河吧。


一、四月,我还以为它是我们的重装皮卡

四月,我还在为基于 DDEV + FrankenPHP + Drupal 11 的后端系统不断折腾,研究 OpenSearch 和 next-drupal,想把 Drupal 11 打造成我们的"后端重装皮卡",在它头上构建微服务和各种 API。甚至我们的 Gen²AI 的第一个版本,所有数据和 API 都通过 Entity 体系注册到了 Drupal 11 的统一后端。

不过我发现我错了。

时代真的变了。

我感觉如果我继续这样子开发下去,就有点像在六十六岁的夏文汐女士身上寻找鱼玄机和 Kathy 的那种程序员才会有的技术栈迷梦了。

我不能说 Drupal 已经在整个 2026 的 Vibe IT 时代完全彻底没落,但是我觉得它正在以超重力的形式走下坡路。


二、一个社区的迟钝

Drupal 社区对 Vibe Coding 反应的迟钝,是我不能忍的。光是一个 chatbot、一个 AI integration 的工程哲学,他们根本就没有任何深入的、自我割命的尝试。

我真的没想到,在 AI 都可以随便 vibe all kinds of shit experience 的时代,Drupal 竟然还在慢吞吞地推进他们的所谓统一体验和组件式开发。

Drupal 社区领导力的匮乏、对开发者的傲慢,是这个系统必将更快腐朽溃烂、并在整个 API 世界销声匿迹的根因。

PHP 基金会都接纳了 FrankenPHP——一个用 Go 缝合了 Caddy 与 PHP Runtime 的、可以实现 Worker 常驻内存的运行时二进制。

但是 Drupal 社区对 FrankenPHP 适配的冷淡,简直令人发指。

Drupal 这种进程驱动的 CMS 和 Web 渲染器,原来的设计哲学是:Web 端用户请求,就拉起一个进程,开始请求页面。如果有 cache,直接 cache hit;没有缓存,就拉取数据,bootstrap PHP 和 MySQL,生成 HTML,通过 PHP-FPM 返回给 Web Server——Nginx、Apache 或 Caddy——再在浏览器里渲染。

服务端,PHP 进程只负责生成 HTML 字符串;这串 HTML 里混杂的 JS、CSS 和万年不变的 Twig 模板,交给浏览器去解析执行。然后,这一通忙完,进程终止。该存缓存的存缓存;没有缓存的,下次再拉一遍 PHP、MySQL、JS、CSS、Twig……

而 FrankenPHP 的鸡贼在于它提供了 Worker 模式——让 PHP 应用以常驻进程的方式运行。它不再是纯粹的事务驱动了,应用可以常驻内存。Worker 模式的性能提升,是非常大的。

偏个题。PHP 毁在了 PHP 6,但是 PHP 7——特别是 7.4——重回了王座,把 Facebook 非得自己搞的所谓高性能开发平台都给干下去了。当然,性能总是不够的,因为我们把信息进行了太多伪装,在 App 里插入了太多遥测、监视用户行为的特洛伊程序,以及太多不可告人的广告和收割流量的需求。PHP 8 的性能迭代与社区领导力似乎也日趋稳定,直到 FrankenPHP 横空出世——当然也不是,一早还有其他的 PHP 高性能框架。

Anyway,Drupal 觉得自己就是最牛的框架。它有时候让人分不清楚它到底是想做 API,Headless CMS,还是 CMS,还是 Framework。

我真的很奇怪,为什么每一次 PHP 生态里出来一个好的 Web 框架,Drupal 都能视而不见。

Drupal 错过了 App 时代——当初有那么多 Drupal PhoneGap 和 Drupal Android 的尝试,却死守在他们的 CMS 迷梦上——这已经证明他们自我麻醉的精神是非常强大的。

Drupal 作为 API,自己有两个工业标准:REST API 和 JSON:API。不过对于现代 Web App 和 Native App 来说,我觉得 just so so。


三、一个 Website Builder 的立场

不过我不想探讨技术问题了。

因为我只是一个 Website Builder,本来在 Drupal 社区就是被看不起的一群人。

Drupal 社区的宗旨是:如果你不是 developer,那请你雇佣一队我们社区的 developer,和我们认证的 Drupal branding 服务商。你不要想着直接从社区拿到全部能满足你 Website Builder 需求的东西。

这点上,Drupal 社区比 WordPress 还差。WordPress 至少还有那么多廉价的、垃圾的 themes 和 modules,各种各样稀奇古怪的 functions,总能找到那种诱导你花几十刀试一试 premium 功能的开发者。

Drupal 社区干脆不这样。

他们假设你们都是白宫和美国某知名大学,需要一个 CMS 加前端开发适配。你想直接找个 distribution、theme、modules 满足你那些奇怪的需求?对不起,要么雇佣 freelancer,要么自己 coding。

Drupal 7 到 Drupal 8,他们自毁长城。Drupal 7 随便一个 distribution 都可能有十几万的装机量。可是我等 Drupal 8 的 Date API 模块出稳定版,好让我的一个 distribution 可以升级到 D8,竟然等了几年——期间我还重新临幸了一段时间的 WordPress 6。

然后,在我抱怨了一下这个跨版本升级的社区日程和维护状态之后,他们竟然直接把我一个十几年的号给永封了。


四、next-drupal 教我的事

不过我得感谢 next-drupal。它让我了解了真正的 Headless CMS、前端开发与 App 开发,让我最后认识到:其实 Drupal 甚至做一个 API 都不必要了。

我直接从 JSON 和 Markdown 数据拉起页面,比 Drupal 从 MySQL 里沉重地 SQL 出数据、组装成 JSON:API 的全量 HTML output、再交给 Next.js 后端渲染构建页面,要轻快得多。

哦,如果我只有 200 个页面,这还是很快的。但是我有 20000 个页面怎么办?旧时代的"一次全量静态 export 构建",我就得等一万年。

当然,现在社区已经通过增量静态生成(ISR)解决了这个问题,但 Drupal 社区的迟钝依然让我心有余悸。但是如果我要 export:output 再封装为 desktop app 呢?正如我的 divola 所做的。

不过,Drupal 社区听了会建议您升级服务器到 1T 内存、256 Core。

虽然 FrankenPHP 的 Worker 模式我们也实现了,让 API 的数据输出极大地提高了效能——但是,经过四月、五月和六月的磨合与扯皮,以及我们面向 AI Vibe Coding 和 Agentic Express 的极速转型,我们只能把这台"API 重装皮卡"扔在路上了。


五、架构解耦,协议耦合

我们现在是彻底解耦了。

不只是 Backend 的 Headless CMS 和 API 与前端的解耦。

我不知道怎么说,但是我只能说,我们彻底地解耦和微服务化了我们的数据架构和代码结构。

我和我的 AI 攻城狮下的死命令是:架构解耦,协议耦合。

绝对不许跨目录读取其他项目的代码与文件,也不许前端或 Middleware 直接读取数据源;必须通过最简的独立 API 输出所需要的数据到相应的 App,必须用 App Router 来解耦。

现在所有的东西都是鸡零狗碎。

没有什么 Bootstrap,没有什么统一的 Developing Experience 了。

只有一个统一的 Design System——而且是面向 AI 攻城师的 Design System V2.0:

https://github.com/sealionking/divo-web-design-system

我们的原则是:人类用户的信息获取是传统技术文档的线性阅读——从上到下,信息密度低,读者容易迷路。DiVo Web Design System 把每个页面设计为 graph 中的一个节点:

  • 锚(Anchor):从人的需求出发,三类读者导航,降低认知压力
  • 流(Flow):技术管线流动,每步可验证,提高信息密度
  • 深(Depth):验证证据可追溯,诚实边界不夸大
  • 能(Capacity):能力架构回溯,双向连通知识图谱

然后我们还直接面向 AI Agent 开发了第五层:Pure Data 和 Knowledge 速取速滚层。

一个爬虫或者 AI Agent 来到我们的网站,它都不需要解析 HTML 和 DOM,直接就能通过我们预设的接口、知识图谱和无渲染的全系数据接口,一瞬间得到我们的所有。那首歌怎么唱的来着,你一直给!

因为我们不需要遥测用户,我们也不需要锁死数据。如果需要锁死的,那我们就不会 pub 到前端的 Web App 里来——在 Nginx domain conf 的更上游一层我们就上锁了。哦,我们也不需要点击量,我们只需要 express 我们的信息出去。

这就是我的设计原则:信息数据化,数据再信息化。 但访客数据不是我需要的。我不是广告商,我也不想靠有限的访客数据去屎上雕花地改进我们所谓的 SEO、GEO。我直接是 GAO——这里的 A 代表 Agent,很有意思,竟然是搞的拼音。

你来,你拿你想要拿的;你走,那你走吧。我只在乎我们的 express,不在乎用户的停留、点击、扫描,还是如何。

你要扫描我的网页,我直接把所有数据一锅煮扔给你的爬虫。你的爬虫面对一个不需要解析 DOM 就能获得数据的网站,不至于一定要浪费我们的 Web 渲染计算资源了吧?

求求你们了!拿到了你们想要的东西,快点回去交差吧。

所以我也不在乎 Drupal 了,不在乎 PHP。虽然我觉得 FrankenPHP 实现 Worker 的模式很性感,不过我已经过了感性地开发 Web 的年纪了。

我老了,我只想 Vibe Coding,我不想钻研那些编程技术了。


六、一副冷冻停尸房

所以我和我的 AI 攻城师总管说:我要把原来基于 Drupal、FrankenPHP 和 DDEV 做的工作做一下告别的归档了。对社区有用的东西开源,发布到我的 GitHub 账户;不能开源的部分 private 保存在归档目录;本地也留一份,放到 USB 盘的 colddata 去。

然后,在我亲手敲下 Drupal 和 PHP 的丧钟这段短暂的时间里,它就把入殓的工作做好了:

  • 开源(MIT):drupal-decoupled-content-export(node_export_json_md + divoblog_api)、drupal-frankenphp-worker(Worker 模式文档 + PHP 8.5 补丁)
  • Private 归档:drupal-cms-2-archive、divo-drupal-cms-customize-archive
  • USB 冷备/usbxijie8t/colddata/drupal-farewell-20260722/——bundle 全历史 + DB dump + 1.8G 站点文件 + FrankenPHP 二进制 + 内部文档。冷备保留了清洗前的完整历史,remote 是干净版,冷备是完整版,各得其所。

我说,不急吧,都放到冷数据吧。万一到时候我们现在的前端某些数据还欠缺,需要去找呢。我 10 年前有个 Gmail 账户被停用了,去年我去找谷歌要,他们竟然又给我恢复了。我们对于数据的历史存档,还是要有这个概念——不要随手就想着这里也删掉、那里也删掉。把它们冻结和归档就行了,万一有查询和恢复激活的需求呢?

我不知道别人都是怎么 Vibe Coding 的,但是在我这干活的 AI 程序员,逐渐地都得根据我的数据架构、我的工作原则、我"信息数据化、计算、数据再信息化"的基本原则,来融入我们的工作环境。这一天,这条哲学也立进了我们的主控室:冻结优先于删除——清理 ≠ 物理消灭,= 冻结到冷数据,为未来的查询与复活保留可能。

所以,其实我们只是给我们所有的 Drupal 历史准备了一副冷冻停尸房而已。我想,如果要真的火化它们,还得再过一两三四五六年吧。或者找一个 1T 的老硬盘,永久性地让它挺尸算了。

也算是,我对 Drupal 带我进入 Website Building 和 Computing Architect 领域的,最后的致谢吧。


七、尾声

2000 年,注册了第一个邮箱。

2001 年,开始学习做网站。那时候 PHP 还用它的本名,Personal Homepage Tools.

2005 年,进入 Drupal Website Building。

两个年代的盘桓,一个时代的终结。

我也该走了。

Goodbye, my Drupal fellows!


归档模块

Module Description
drupal-site-toolkit Site toolkit utilities
drupal-ragflow-auth RAGFlow authentication integration
drupal-pgvector-search PostgreSQL pgvector search integration
drupal-ai-llm-providers AI/LLM provider integrations
drupal-frankenphp-worker FrankenPHP worker support
drupal-decoupled-content-export Decoupled content export

Each module lives in its own directory, preserving original git history via subtree merge.


Freeze over delete. Archive over annihilate. For the possibility of future query and resurrection.

About

Farewell Drupal: consolidated Drupal modules — site-toolkit, ragflow-auth, pgvector-search, ai-llm-providers, frankenphp-worker, decoupled-content-export

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages