monolyth / formulaic
Monolyth 无框架面向对象表单工具
Requires
- php: >=8.1
Requires (Dev)
- gentry/gentry: ^0.16
- toast/unit: ^2.1.7
- dev-master
- 1.12.10
- 1.12.9
- 1.12.8
- 1.12.7
- 1.12.6
- 1.12.5
- 1.12.4
- 1.12.3
- 1.12.2
- 1.12.1
- 1.12.0
- 1.11.6
- 1.11.5
- 1.11.4
- 1.11.3
- 1.11.2
- 1.11.1
- 1.11.0
- 1.10.11
- 1.10.10
- 1.10.9
- 1.10.8
- 1.10.7
- 1.10.6
- 1.10.5
- 1.10.4
- 1.10.3
- 1.10.2
- 1.10.1
- 1.10.0
- 1.9.10
- 1.9.9
- 1.9.8
- 1.9.7
- 1.9.6
- 1.9.5
- 1.9.4
- 1.9.3
- 1.9.2
- 1.9.1
- 1.9.0
- 1.8.4
- 1.8.3
- 1.8.2
- 1.8.1
- 1.8.0
- 1.7.12
- 1.7.11
- 1.7.10
- 1.7.9
- 1.7.8
- 1.7.7
- 1.7.6
- 1.7.5
- 1.7.4
- 1.7.3
- 1.7.2
- 1.7.1
- 1.7.0
- 1.6.20
- 1.6.19
- 1.6.18
- 1.6.17
- 1.6.16
- 1.6.15
- 1.6.14
- 1.6.13
- 1.6.12
- 1.6.11
- 1.6.10
- 1.6.9
- 1.6.8
- 1.6.7
- 1.6.6
- 1.6.5
- 1.6.4
- 1.6.3
- 1.6.2
- 1.6.1
- 1.6.0
- 1.5.11
- 1.5.10
- 1.5.9
- 1.5.8
- 1.5.7
- 1.5.6
- 1.5.5
- 1.5.4
- 1.5.3
- 1.5.2
- 1.5.1
- 1.5.0
- 1.4.3
- 1.4.2
- 1.4.1
- 1.4.0
- 1.3.0
- 1.2.3
- 1.2.2
- 1.2.1
- 1.2.0
- 1.1.0
- 1.0.2
- 1.0.1
- 1.0.0
- 0.0.13
- 0.0.12
- 0.0.11
- 0.0.10
- 0.0.9
- 0.0.8
- 0.0.7
- 0.0.6
- 0.0.5
- 0.0.4
- 0.0.3
- 0.0.2
- 0.0.1
- dev-dependabot/composer/twig/twig-3.14.0
- dev-develop
This package is auto-updated.
Last update: 2024-09-09 20:53:25 UTC
README
PHP8.1+ 的面向对象表单工具
HTML 表单很糟糕。好吧,不,它们超级实用,但编写和服务器端验证它们可能会有点麻烦。Formulaic 提供了一系列工具来减轻这种痛苦。
基本用法
定义一个包含一些字段和其他要求的表单
<?php use Monolyth\Formulaic\Get; use Monolyth\Formulaic\Search; use Monolyth\Formulaic\Button\Submit; class MyForm extends Get { public function __construct() { $this[] = (new Search('q'))->isRequired(); $this[] = new Submit('Go!', 'submit'); } }
在您的模板中,可以使用 API 手动调整输出,或者简单地使用 __toString
表单来使用默认值
<?php $form = new MyForm; echo $form;
您可以 __toString
单个字段
<?php $form = new MyForm; ?> <form name="search" method="get"> <!-- These two yield identical output using MyForm above: --> <?=$form[0]?> <?=$form['q']?> </form>
要验证表单
<?php $form = new MyForm; if ($form->valid()) { // ...Perform the search... }
要获取错误列表
<?php $form = new MyForm; if ($errors = $form->errors()) { // ...Do error handling, or give feedback... }
表单可以包含字段集
<?php use Monolyth\Formulaic\Get; use Monolyth\Formulaic\Fieldset; use Monolyth\Formulaic\Search; use Monolyth\Formulaic\Button\Submit; class MyForm extends Get { public function __construct() { $this[] = new Fieldset('Global search', function($fieldset) { $fieldset[] = new Search('q'); }); $this[] = new Fieldset('Search by ID', function($fieldset) { $fieldset[] = new Search('id'); }); $this[] = new Submit('Go!'); } }
在您的输出中
<form method="get"> <?=$form['Global search']?> <?=$form['Search by ID']?> <?=$form['submit']?> </form>
表单中的自定义元素
只需将字符串添加到表单中;它们将原样输出
<?php // ... class Form extends Get { public function __construct() { $this[] = new Radio('foo'); $this[] = '<h1>custom HTML element!</h1>'; } }
内部机制
正如您所猜测的,Post
和 Get
表单分别查看提交和获取数据。这意味着在超全局变量中(对于 Post
,包括 $_FILES
)的任何匹配数据都将自动设置在表单上。对于组中的元素(不包括字段集),Formulaic 假设它们将位于一个子数组中
<?php use Monolyth\Formulaic\{ Get, Element\Group, Text }; class Form extends Get { public function __construct() { $this[] = new Group('foo', function ($group) { $group[] = new Text('bar'); }); } }
这将与 $_GET['foo']['bar']
的值匹配。
对于复选框组(一组相关复选框,例如设置),值假设在它们自己的数组中。例如,对于名为 'foo' 的复选框组,值将作为 $_POST['foo'] = [1, 2, 3]
传递。
添加测试
表单元素可以包含测试,这些测试由 valid()
和 error()
方法使用以生成输出。提供了一些预定义的测试(如 isRequired()
),但您可以通过元素上的 addTest
方法轻松添加自己的测试
<?php $input = new Text('foo'); $input->addTest(fn ($value) => $value == 'bar');
除非用户将 "bar" 输入到文本输入框中,否则上述测试将失败。
绑定模型
Formulaic 在传播表单数据到您的模型方面也表现出色。所有包含大量 isset
调用的样板代码?消失了!
您的模型是一个对象。字面上任何对象。您想要的是任何属性的先前填充值自动设置在您的表单上,并且用户输入的任何值都更新在对象上(然后您可以将其持久化到数据库或任何其他地方,这取决于您)。 猜猜看?这很简单!
<?php class MyFrom extends Post { //... define the form public function __construct() { $this[] = new Text('foo'); } } $model = new stdClass; $model->foo = 'bar'; $form = new MyForm; $form->bind($model);
在上面的示例中,相关的表单(当 __toString
时)将为 foo
输入设置默认值 "bar"
。如果 $_POST['foo']
竟然包含 "buzz"
,则它将包含 那个。更好的是,在调用 bind
之后,也将如此,使得 $model->foo === 'buzz'
等于 true。太棒了!那是您不再需要考虑的数百万行代码!
绑定可以在任何级别上进行,只需记住它需要在对象上,并且其(子)属性必须与元素的名称匹配。
您会注意到这将模型结构绑定到表单构建上;然而,这并不重要。表单元素按原样显示,只需它们的名称需要与模型匹配。
转换数据
在现实世界中,模型对象通常比基本处理字符串的 HTML 表单要复杂得多。这就是转换器的用武之地:Formulaic 将数据转换为您的模型的方式。
所有元素都支持 withTransformer
方法,该方法基本上接受一个可调用函数。这里的想法是可调用函数的参数是类型提示的(以便确定要使用哪个转换器),并基于该类型返回一个合适的值。某个特定情况的可接受转换器可能是
<?php class MyModel { public Foo $foo; } class MyForm extends Post { public function __construct() { $this[] = (new Text('foo')) ->withTransformer(fn(string $value) => new Foo($value)); } } $model = new MyModel; $form = new MyForm; $form->bind($model); echo get_class($model->foo); // Foo
您可以使用 withTransformers
方法(注意复数)一次定义多个转换器。每个参数都是一个可调用函数。
通常,你需要两个变压器:一个从模型到表单,另一个从表单返回到模型。在某些情况下,输入可能会根据你项目的复杂度而变化;定义你需要的变压器数量。
输入类型提示可能是一个 联合体,在这种情况下,变压器适用于多种类型。交集类型提示不支持,因为在转换上下文中它们并不真正有意义。
GET 表单陷阱!
在 PHP 中,无法区分“常规”页面加载和由提交的 GET 表单触发的页面加载(与 POST 请求不同)。为了确定用户是否提供了值,Formulaic 简单地检查 $_GET
是否为真。请注意,这可能或可能不足以满足你的需求;理论上,一个完全为空的表单也可以提交,这将仍然触发此操作,或者 URL 可能已经包含(无关的)GET 参数。
在这些边缘情况下,扩展 Get
表单并实现你自己的 wasSubmitted
方法进行替代检查,例如检查隐藏表单字段或命名提交按钮。
对于 POST 表单,假设用户在 $_SERVER['REQUEST_METHOD'] == 'POST'
时提供了值。同样,可能存在这种检查对你来说不够好的情况 - 扩展并重写,再次。
GET 或 POST 之外的方法
在这种情况下,PUT 或 DELETE 可能会出现。这些不是开箱即用的,因为 Formulaic 是一个 HTML 表单库,而 HTML 只支持 GET 和 POST。然而,你可能会希望在处理 AJAX 调用的控制器中使用验证和绑定逻辑。在这种情况下,你可以自由地扩展你自己的表单类。
任何扩展都将需要实现 getSource
方法,例如对于 PUT,你需要手动解析 file_get_contents('php://input')
。由于我们无法知道它包含的内容(可能是 JSON,但假设是所有错误的源头...)你需要编写适合你需求的自己的实现。
类似地,DELETE 可以 在 URL 中包含 GET 数据。我们并不确定何时需要这种情况,但这里有了它 - 自定义 Delete
表单可能扩展 GET。