broeser / feeld
Feeld提供可类型化的字段对象,可以用作构建CLI调查问卷、HTML表单等的基本模块。包括清理和验证。
Requires
- php: >=5.6.0
- broeser/sanitor: dev-master
- broeser/wellid: >=0.4.0
Requires (Dev)
- symfony/console: ^3.0
This package is not auto-updated.
Last update: 2024-09-14 18:26:15 UTC
README
/ 这是一个非常早期的未完成工作,没有任何发布版本,几乎没有测试,也没有适当的文档 /
Feeld提供可类型化的字段对象,可以用作构建CLI调查问卷、HTML表单等的数据模型的基本模块。包括清理和验证,以及示例UI实现。
目标
- Feeld追求数据模型和显示之间的严格分离,应该可以在HTML、GTK或CLI中以最小的代码更改显示相同的字段。
- Feeld旨在通过自己的数据类型、字段类型、显示(UI组件)和其他增强功能合理地扩展。
- Feeld应该尽可能容易学习和使用,同时不失灵活性。
注意
如果您只对Feeld的“清理和验证”方面感兴趣,而不是预定义的数据类型和表单构建块,那么使用broeser/sanitor和broeser/wellid可能更好——这两个包比Feeld更容易使用。
安装
Feeld支持PHP 5.6和7.0。
可以通过composer安装此包
composer require broeser/feeld
如何使用
数据类型 – 清理和验证的包装器
数据类型是默认清理程序、默认验证器和一些基本方法(例如setMinLength()和setMaxLength())的组合,用于指定边界。
这些数据类型由Feeld在src/DataType目录中提供
- 布尔值
- 国家
- 日期
- 电子邮件
- 文件
- 浮点数
- 整数
- 字符串(Str)
- URL
使用数据类型进行清理和验证
可以使用数据类型对值进行清理和验证。
示例
<?php $myIntType = new \Feeld\DataType\Integer(); $myIntType->setMinLength(2); // 2 digits $result = $myIntType->validateValue('f9'); if($result->hasErrors()) { print($myIntType->getLastSanitizedValue().' was invalid. This is the first error:'.PHP_EOL); print($result->firstError()->getMessage().PHP_EOL); }
在示例中,一个整数被设置为一个约束,即它至少要有2位数字。然后通过调用validateValue()对值'f9'进行验证。因为'f9'在验证开始之前被清理为整数9,所以“至少2位数字”的规则不满足,$result->hasErrors()为true。getLastSanitizedValue()是getSanitizer()->filter($value)的缩写。它将始终返回通过validateValue()提供给此数据类型的最后一个清理后的值。
对Feeld使用的验证组件wellid的基本理解可能会有所帮助,特别是关于ValidationResults和ValidationResultSets。阅读wellid的README是推荐的。
字段
字段是实现FieldInterface类实例的对象。这些类位于src/Field/…
它们定义了数据输入的类型(例如,“选择几个值之一”,“勾选框”或“输入文本”。请注意,这与字段的UI无关:“选择几个值之一”可能通过单击值或输入值来完成;有关Feeld的UI组件,请参阅显示。
每个字段在构造时必须分配一个数据类型。在构造时为每个字段分配一个字符串标识符是可选的,但推荐这样做。这样就可以更容易地区分不同的字段。
示例
<?php $myStringSelector = new Feeld\Field\Select(new Feeld\DataType\URL(), 'myFunnyField1'); $myStringSelector->setRawValue('http://example.org'); if($myStringSelector->validateBool()) { print($myStringSelector->getFilteredValue().' is a valid url!'); } else { print('Invalid URL'); }
此示例定义用户可以选择多个URL之一。已选择了http://example.org。因为这是一个有效的URL,所以下面显示的消息。该消息使用“过滤后的值”(净化后的值)。
对于HTML表单输入或通过API输入,可以使用rawValueFromInput()方法
<?php $myStringSelector = new Feeld\Field\Select(new Feeld\DataType\URL()); $myStringSelector->rawValueFromInput(INPUT_REQUEST, 'url'); if($myStringSelector->validateBool()) { print($myStringSelector->getFilteredValue().' is a valid url!'); } else { print('Invalid URL'); }
这些字段由Feeld提供
- 复选框 - 通过选中或不选中原则/是或否原则进行数据录入
- CloakedEntry - 隐藏数据录入,UI不应显示与输入相同的数据(例如密码字段)
- 常量 - 忽略用户输入(如果有)并使用常量值
- Entry - 默认数据录入
- Select - 通过选择多个值之一(或多个)进行数据录入
如果您想创建自己的字段,可以使用CommonProperties\Field特质(如果您的字段需要可净化和可验证,则与\Wellid\SanitorBridgeTrait结合使用)或扩展使用这些特质的抽象类AbstractField。
显示
显示是实现了DisplayInterface的类的实例。这些类位于src/Display/…。
它们可用于显示字段的UI(字段的本身,不一定字段值)。这可以是问题字符串('您确定[y/N]?'),HTML形式('<input type="checkbox" name="sure" value="y">'),GtkEntry小部件或其他任何您能想到的形式。
提供了SymfonyConsoleDisplay以用于与Symfony控制台组件一起使用Feeld。
请注意,一个显示实例仅显示一个字段,因此对于具有两个字段的表单,您还需要两个显示实例。
您可以将显示转换为字符串(例如,echo (string)$myDisplay;)。对于无法表示为字符串的显示,可能会返回类似var_dump的内容。
虽然不太有用,但可以在不使用字段的情况下完全使用显示。
<?php $myDisplay = new Feeld\Display\HTML\Input('email'); print($myDisplay); // will print <input type="email">
通常,显示用作字段的UI。可以通过调用setDisplay()方法将现有的显示设置为字段的UI。
<?php $myDisplay = new Feeld\Display\HTML\Input('email'); print($myDisplay); // will print <input type="email"> $myField = new Feeld\Field\Entry(new Feeld\DataType\Email()); $myField->setRequired(); $myField->setDisplay($myDisplay); print($myDisplay); // will – hopefully – print something like // <input type="email" required>
如果您更喜欢完全不将字段与显示耦合的方法,可以在上面的示例中使用$myDisplay->informAboutStructure($myField)代替setDisplay调用。
您还可以在构造字段时指定显示作为参数。
示例
<?php $myStringSelector = new Feeld\Field\Select(new Feeld\DataType\URL(), 'yourhomepage', new Feeld\Display\HTML\Input('radio')); $myStringSelector->addOption('http://example.org'); $myStringSelector->addOption('invalidoption'); $myStringSelector->rawValueFromInput(INPUT_REQUEST, 'url'); if($myStringSelector->validateBool()) { print($myStringSelector->getFilteredValue().' is a valid url!'); } else { print('Invalid URL. Please select a valid URL!'); print($myStringSelector); /* returns something like <input type="radio" name="" value="http://example.org"><input type="radio" value="invalidoption"> */ }
示例定义用户可以选择多个URL之一。为了显示此选择,使用了-HTML标签。
字段集合
字段可以分组在FieldCollection中。如果您想编写自己的字段集合,请确保实现FieldCollectionInterface。您可以使用FieldCollectionTrait来获取一些基本代码。
字段可以在构造时或使用addField() / addFields()-方法添加到字段集合中。可以检索强制/必需字段的集合(getMandatoryFields()),通过id获取特定字段(getFieldById()),通过其数据类型的类名(getFieldsByDataType())或通过字段本身的类名。
字段集合是可计数的和可迭代的。
如果也使用UI(显示),可以使用setFieldDisplay($fieldId, $fieldDisplay)方法为具有给定字段标识符的字段集合中的字段指定显示。
可以一次性对整个字段集合进行validate()。经过验证的字段值将存储在对象中(默认为\stdClass,可以通过分配值映射器进行配置(见下文))。验证后,可以使用getValidAnswers()检索答案。正如方法名所示,只有通过验证的值将包含在答案对象中。
值映射器和值映射策略
ValueMapper 用于将对象的属性设置为特定值。虽然最重要的用例是定义如何存储从 FieldCollection 验证后的值,但 ValueMapper 也可以在不需要 FieldCollection 的情况下使用。
在这个简单的例子中,ValueMapper 将 MyClass 对象的“email”属性设置为值,但不会设置其他属性。
<?php use Feeld\FieldCollection\ValueMapper; use Feeld\FieldCollection\ValueMapStrategy; class MyClass { public $name; protected $email; private $internalCounter; } $valueMapper = new \ValueMapper(new MyClass(), ValueMapStrategy::MAP_REFLECTION, array('email')); // Sets the email $valueMapper->set('email' => 'test@example.org'); // Does nothing and returns false, because "name" is not registered with the ValueMapper $valueMapper->set('name' => 'MyName');
构造函数的第一个参数接受应更改属性的对象。第二个参数是 ValueMapStrategy 的默认类型。这意味着 ValueMapper 可以使用不同的技术来设置值
- MAP_REFLECTION:使用反射,可以用来设置私有/受保护的属性
- MAP_PUBLIC:可以用来设置公共属性(默认值)
- MAP_SETTER:使用设置器方法(此示例的默认值为 "setEmail",可以配置)
第三个(可选)参数是 ValueMapper 应处理的全部属性数组。可以通过使用 addProperty('name') 方法添加更多属性。此方法还允许为每个属性使用不同的 ValueMapStrategy
<?php use Feeld\FieldCollection\ValueMapper; use Feeld\FieldCollection\ValueMapStrategy; class MyClass { private $mailAdress; public $homepage; public $name; public function saveEmailAndStuff($mail) { $this->mailAddress = $mail; if($mail==='red_flag@donotuse.example.org') { $message = new InformManager('Someone used the secret email!'); $message->send(); } } } $valueMapper = new ValueMapper(new MyClass(), ValueMapStrategy::MAP_PUBLIC, array( 'name', 'url' => 'homepage' )); $valueMapper->addProperty('email', new ValueMapStrategy(ValueMapStrategy::MAP_SETTER, 'saveEmailAndStuff')); // calls saveEmailAndStuff with with parameter mail@example.org $valueMapper->set('email', 'mail@example.org'); // Sets the public property $homepage to http://example.org $valueMapper->set('url', 'http://example.org'); // Sets the public property name to MyName $valueMapper->set('name', 'MyName');
可以通过在 FieldCollection 上调用 addValueMapper($valueMapper) 将 ValueMapper 分配给 FieldCollection。这应该在验证之前完成。
可以为 ValueMapper 分配一个 id 以区分多个不同的 ValueMapper:可以使用 setId()、hasId() 和 getId()。
面试
面试通常基于 FieldCollections 构建。它们以问题的形式将 FieldCollections 中的每个 Field 展示给用户。用户被邀请回答这些问题,答案将被清理、验证并可以存储。
Interview 的主要入口点是构造函数之后的 execute() 方法。
一旦 Interview 类被 **execute()**,它将管理以下逻辑
- 邀请用户回答问题( inviteAnswers())
- 从用户那里检索答案( retrieveAnswers())
- 清理和验证这些答案
- 在 onValidationError() 和 onValidationSuccess() 上执行不同的操作
- 设置状态码,根据答案是否有效,可以通过 getStatus() 获取
- 可选地分支到另一组答案或结束面试
您可以使用 InterviewInterface 与 InterviewStatusTrait 一起创建自己的逻辑,以精确地执行这些步骤。如果您更愿意扩展抽象类,则可以使用 AbstractInterview。
对于多页/分支的面试,请使用 TreeInterviewInterface(而不是 InterviewInterface)和 TreeInterviewTrait。还提供了 AbstractTreeInterview。
目前有两种 Interviews 的示例实现可用
- HTML表单
- Symfony 控制台
HTML表单 在 HTML5 表单的上下文中提出问题。它以以下方式处理上述步骤
- 邀请用户回答问题:在源代码中显示它们
- 从用户那里检索答案:使用 filter_input()
- 清理和验证这些答案:使用分配给 Interview 的 FieldCollection 中的 Fields(及其分配的验证器/清理器)
- onValidationError:所有错误消息都显示在无序列表中
- 状态码:STATUS_VALIDATION_ERROR(无效数据)、STATUS_AFTER_INTERVIEW(成功)或 STATUS_BEFORE_INTERVIEW(表单尚未提交)
Symfony 控制台 使用 Symfony 控制台组件来提出问题。
您可以在 examples/-目录中找到这两个 Interview 实现的工作示例(example_html5_form.php 和 example_symfony_console.php)。后者可以通过以下方式运行
php example_symfony_console.php run
Feeld?
这是对“That feels right”和“Field”的双关语。