Skip to content

介绍 ​

这一篇讲为什么这样设计,以及它不适合什么场景。

如果你只想跑起来,去看安装。

三个核心决策 ​

决策一:把「域」做成第一等公民 ​

问题:PC 站、移动 App、小程序、后台——四个端的接口形态不同,但业务规则相同。

多数框架里这会变成:

php
// 每多一个端,就多一个 controller
class WebPostController { /* 复制一遍 */ }
class AppPostController { /* 复制一遍 */ }
class MiniappPostController { /* 复制一遍 */ }

或者:

php
// 一个 controller 里到处判断
if ($platform === 'web') { ... }
elseif ($platform === 'app') { ... }

这个框架的做法:

php
// config/api.php
'domains' => [
    'admin' => ['prefix' => 'admin', 'versions' => ['v1'], 'middleware' => ['auth']],
    'web'   => ['prefix' => 'web',   'versions' => ['v1']],
    'app'   => ['prefix' => 'app',   'versions' => ['v1']],
],

每个域独立前缀、独立版本、独立中间件,共用同一批领域服务:

php
// 三个域的控制器都调同一个 PostService
return $this->posts->paginate(page: 1, perPage: 20);

额外的好处:token 天然不跨域。

web 域签发的 token 访问 admin 域会返回 401——因为 token 里绑定了域标识。这省掉了大量「这个用户能不能访问这个接口」的判断。

代价:域的划分需要前期想清楚。如果一开始只做一个域,后来要拆,路由要重组。

决策二:零运行时依赖 ​

问题:Composer 生态很强大,但也带来部署摩擦。

  • 协作时 composer.lock 冲突
  • 生产环境要装 Composer 或传 vendor/
  • 依赖漏洞要跟踪升级
  • 一个包更新可能连锁影响十几个包

这个框架的做法:核心不用任何第三方包。

bash
$ grep -r '^use [A-Z]' core/ | grep -v SunsetReverie
(无输出)

代价是自己实现了不少东西:PSR-4 自动加载、容器、查询构造器、JWT、SMTP 客户端。

取舍点:

自己实现的好处代价
出问题能立刻定位到具体代码功能不如成熟轮子完善(比如 SMTP 不支持 TLS)
部署零摩擦某些边界情况需要自己踩(比如三库方言差异)
没有版本升级焦虑性能优化要自己做

边界写清楚:SMTP 不支持 TLS 是刻意的。证书校验、SNI、协议降级手写极易出错,而发邮件 90% 走内网 relay 或第三方 API。需要加密时部署本地 relay 转发。

决策三:不做 ORM ​

问题:ORM 让简单查询变简单,让复杂查询变复杂。

php
// ORM 风格
$posts = Post::with('author', 'tags')
    ->whereHas('comments', fn ($q) => $q->where('status', 1))
    ->get();

这段代码生成了几条 SQL?只有跑一遍才知道。

N+1 问题在开发环境感知不到(本地数据库 1ms),上线后才发现(远程 5ms × 200 次 = 1 秒)。

这个框架的做法:

php
$posts = DB::table('posts')
    ->select('id', 'title', 'author_id')
    ->where('status', 1)
    ->limit(20)
    ->get();

// 作者单独查一次,而不是每行查一次
$authors = DB::table('users')
    ->whereIn('id', array_column($posts, 'author_id'))
    ->get();

SQL 在眼前,查了几次库一目了然。

代价:关联查询要自己写。一对多、多对多不会自动帮你处理。

为什么接受这个代价:真实业务里,复杂查询往往需要针对索引优化,ORM 生成的 SQL 未必合适。而简单查询手写并不麻烦。

它不适合什么 ​

诚实地说:

场景为什么不适合
需要庞大生态没有现成的管理后台、CMS、支付集成
重度关联业务十几个表互相关联时,手写 JOIN 会很痛苦
团队已熟悉主流框架学习成本 vs 收益不划算
需要开箱即用这里只有骨架,业务要自己写
需要复杂权限体系只提供了中间件 + 服务内判断,没有 Gate/Policy

它适合什么 ​

场景为什么
多端共存的业务后端域隔离直接解决「四套 controller」的问题
一个人维护的项目没有魔法,出问题能快速定位
部署环境受限不能装 Composer 也能跑
想读懂每一行执行路径55 个 core 文件,全都能读完
团队规模小少一层抽象,沟通成本低

和其他框架的定位差异 ​

夕梦LaravelSlim
依赖零运行时依赖大量第三方包少量依赖
ORM无Eloquent无(自带 PDO 封装)
多域内置需自行组织需自行组织
生态无极丰富中等
学习曲线中(需理解域与分层)中低
适合规模中型任意小型

不是替代关系。如果你的项目适合 Laravel,就用 Laravel——它的生态能省下大量时间。

这个框架的存在理由是:当项目形态是「多端 + 小团队 + 不想被依赖绑架」时,它比主流框架更合适。

设计原则 ​

框架内部遵循几条硬规则,由 sr lint:architecture 自动检查:

编号约束
ARCH-1内核不得引用业务命名空间
ARCH-2内核不得引用第三方包
ARCH-3组件之间无未声明的互相依赖
ARCH-4内核仅组装层(Application / Facades)依赖组件
ARCH-7Facade 的 @method 与底层类一致
ARCH-8组件目录与 autoload 映射表一致

不通过即阻断合并。这几条的价值在于:它们约束的是「依赖方向」,而依赖方向一旦腐烂,重构成本会指数上升。

下一步 ​

以 MIT 许可发布 · v1.0 夕照