
从相同模式自动生成的表单
19 Jul 2026
表单通常是构建管理界面中最繁琐的部分:每个字段的正确输入、客户端和服务器验证保持同步,以及创建表单和编辑表单随着时间的推移悄然分离。在 Phlo 中,创建表单、编辑表单、列表视图和 REST API 都读取完全相同的模式,因此只有一个地方可能出现偏差。
输入遵循类型
static schema => arr(
status: field(type: 'select', options: ['draft', 'sent', 'paid']),
notes: field(type: 'text', multiline: true),
cover: field(type: 'image'),
sent_at: field(type: 'datetime'),
)
一个 select 渲染一个受其声明选项限制的下拉菜单,text 与 multiline: true 一起渲染一个文本区域,而不是单行输入,image 渲染一个带有缩略图预览的上传控件,datetime 渲染匹配的选择器。这些都不是针对每个表单编写的;每种字段类型资源(fields/select、fields/image 等)拥有自己的 input() 渲染,CMS 只是询问架构哪个字段类型拥有给定的列。
在数据到达数据库之前的验证
将模型选项设置为 static objValidate = true 会在 create() 提交任何内容之前,对架构中的每个字段运行匹配的 objValidate($value),在字段上声明的 pattern: 或 enum: 约束与创建表单和创建 API 强制执行的规则相同,因为两者都调用相同的字段对象:
if (!user::create($args)) return apply(errors: user::objErrors())
required: true 更进一步,并在创建和编辑时统一检查;objValidate 的其余部分今天是一个创建时的门槛。无论如何,没有单独的客户端验证库来与一次编写后在前端被悄悄遗忘的服务器端规则保持同步。
CSRF,默认情况下
每个写入,POST、PUT、PATCH、DELETE,都在没有开发者额外配置的情况下受到 CSRF 保护。这并不是一个特定于表单的功能,而是写入路径作为一个共享机制的结果,而不是每个模型一个:只需对机制进行一次安全保护,经过它的每个模型都会自动继承保护。
实际保存
这一切都不是关于任何单个表单看起来好看。关键在于,架构更改、添加字段、收紧验证规则、改变输入类型,会同时更新列表视图、两个表单和 API,因为只需更改一个模型的描述。