b2pweb / bdf-form-attribute
使用 PHP 8 属性和类型化属性声明表单,基于 bdf-form
dev-master / 1.0.x-dev
2024-03-04 11:16 UTC
Requires
- php: ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0
- b2pweb/bdf-form: ~1.1
- nette/php-generator: ~3.6|~4.0
Requires (Dev)
- phpunit/phpunit: ~9.5
- squizlabs/php_codesniffer: ~3.6.1
- symfony/security-csrf: ~5.4|~6.1
- vimeo/psalm: ~5.22
This package is auto-updated.
Last update: 2024-09-26 10:04:29 UTC
README
使用 PHP 8 属性和类型化属性声明表单,基于 BDF 表单
用法
使用 composer 安装
composer require b2pweb/bdf-form-attribute
声明表单类
要使用 PHP 8 属性创建表单,首先必须扩展 AttributeForm。
然后声明所有输入元素和按钮作为属性
- 对于元素:
public|protected|private MyElementType $myElementName;
- 对于按钮:
public|protected|private ButtonInterface $myButton;
最后,在属性(或表单类)上使用属性来配置元素,添加约束,转换...
#[Positive, UnitTransformer, GetSet] public IntegerElement $weight;
BDF 表单示例的改编:处理实体
use Bdf\Form\Attribute\Form\Generates; use Bdf\Form\Leaf\StringElement; use Symfony\Component\Validator\Constraints\NotBlank; use Bdf\Form\Attribute\Child\GetSet; use Bdf\Form\Attribute\AttributeForm; use Bdf\Form\Leaf\Date\DateTimeElement; use Bdf\Form\Attribute\Element\Date\ImmutableDateTime; use Bdf\Form\Attribute\Child\CallbackModelTransformer; use Bdf\Form\ElementInterface; // Declare the entity class Person { public string $firstName; public string $lastName; public ?DateTimeInterface $birthDate; public ?Country $country; } #[Generates(Person::class)] // Define that PersonForm::value() should return a Person instance class PersonForm extends AttributeForm // The form must extend AttributeForm to use PHP 8 attributes syntax { // Declare a property for declare an input on the form // The property type is used as element type // use NotBlank for mark the input as required // GetSet will define entity accessor #[NotBlank, GetSet] private StringElement $firstName; #[NotBlank, GetSet] private StringElement $lastName; // Use ImmutableDateTime to change the value of birthDate to DateTimeImmutable #[ImmutableDateTime, GetSet] private DateTimeElement $birthDate; // Custom transformer can be declared with a method name as first parameter of ModelTransformer // Transformers methods must be declared as public on the form class #[ImmutableDateTime, CallbackModelTransformer(toEntity: 'findCountry', toInput: 'extractCountryCode'), GetSet] private StringElement $country; // Transformer used when extracting input value from entity public function findCountry(Country $value, ElementInterface $element): string { return $value->code; } // Transformer used when filling entity with input value public function extractCountryCode(string $value, ElementInterface $element): ?Country { return Country::findByCode($value); } }
支持的属性
此库支持各种属性类型来配置表单元素
- Symfony 验证器的
Constraint
,翻译为...->satisfy(new Constraint(...))
ExtractorInterface
,翻译为...->extractor(new Extractor(...))
HydratorInterface
,翻译为...->hydrator(new Hydrator(...))
FilterInterface
,翻译为...->filter(new Filter(...))
TransformerInterface
,翻译为...->transformer(new Transformer(...))
从属性生成配置器代码
为了提高性能,并避免使用反射,可以使用属性来生成配置器的 PHP 代码,而不是动态配置表单。
为此,将 CompileAttributesProcessor
作为表单构造函数的参数使用。
const GENERATED_NAMESPACE = 'Generated\\'; const GENERATED_DIRECTORY = __DIR__ . '/var/generated/form/'; // Configure the processor by setting class and file resolvers $processor = new CompileAttributesProcessor( fn (AttributeForm $form) => GENERATED_NAMESPACE . get_class($form) . 'Configurator', // Retrieve the configurator class name from the form object fn (string $className) => GENERATED_DIRECTORY . str_replace('\\', DIRECTORY_SEPARATOR, $className) . '.php', // Get the filename of the configurator class from the configurator class name ); $form = new MyForm(processor: $processor); // Set the processor on the constructor $form->submit(['firstName' => 'John']); // Directly use the form : the configurator will be automatically generated // You can also pre-generate the form configurator using CompileAttributesProcessor::generate() $processor->generate(new MyOtherForm());