支付宝扫一扫付款
微信扫一扫付款
(微信为保护隐私,不显示你的昵称)
通过使用type guesser(类型猜测器),表单组件可以猜出字段的“类型及部分选项”。本组件自带了一个“使用Validator组件的assertions(断言)”的type guesser,但你也可以添加自定义的type guesser。
本节,你要建立一个guesser,可以从属性上面的PHPDoc中读取字段信息。首先,你要创建一个类,令其实现FormTypeGuesserInterface接口。该接口有4个方法:
guessType() - 尝试猜测一个字段类型;
guessRequired() - 尝试猜测一个required选项;
guessMaxLength() - 尝试猜测一个maxlength input属性的值;
guessPattern() - 尝试猜测pattern input属性的值。
先用这几个方法把类建立起来。然后,你要学习如何填充每个方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | namespace Acme\Form;
use Symfony\Component\Form\FormTypeGuesserInterface;
class PHPDocTypeGuesser implements FormTypeGuesserInterface
{
public function guessType($class, $property)
{
}
public function guessRequired($class, $property)
{
}
public function guessMaxLength($class, $property)
{
}
public function guessPattern($class, $property)
{
}
} |
猜测一个类型时,方法返回的是TypeGuess实例,或什么也不返回以确定guesser不能猜测出这个类型。
TypeGuess类的构造器有三个参数:
类型的名称(需是form types之一);
附加选项(例如,当类型是entity时,你同时希望设置其class选项)。如果没有任何类型被猜中,此处被设置为一个空数组;
猜出来的类型“有多正确”之confidence(自信度)。它可以是Guess类中的常量里的一个:LOW_CONFIDENCE,MEDIUM_CONFIDENCE,HIGH_CONFIDENCE,VERY_HIGH_CONFIDENCE。当所有的guessers都被执行过之后,最高自信度的类型将被采纳。
在这些知识的帮助下,你可以去实现PHPDocTypeGuesser的guessType方法了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | namespace Acme\Form;
use Symfony\Component\Form\Guess\Guess;
use Symfony\Component\Form\Guess\TypeGuess;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
class PHPDocTypeGuesser implements FormTypeGuesserInterface
{
public function guessType($class, $property)
{
$annotations = $this->readPhpDocAnnotations($class, $property);
if (!isset($annotations['var'])) {
return; // guess nothing if the @var annotation is not available
}
// otherwise, base the type on the @var annotation
switch ($annotations['var']) {
case 'string':
// there is a high confidence that the type is text when
// @var string is used
return new TypeGuess(TextType::class, array(), Guess::HIGH_CONFIDENCE);
case 'int':
case 'integer':
// integers can also be the id of an entity or a checkbox (0 or 1)
return new TypeGuess(IntegerType::class, array(), Guess::MEDIUM_CONFIDENCE);
case 'float':
case 'double':
case 'real':
return new TypeGuess(NumberType::class, array(), Guess::MEDIUM_CONFIDENCE);
case 'boolean':
case 'bool':
return new TypeGuess(CheckboxType::class, array(), Guess::HIGH_CONFIDENCE);
default:
// there is a very low confidence that this one is correct
return new TypeGuess(TextType::class, array(), Guess::LOW_CONFIDENCE);
}
}
protected function readPhpDocAnnotations($class, $property)
{
$reflectionProperty = new \ReflectionProperty($class, $property);
$phpdoc = $reflectionProperty->getDocComment();
// parse the $phpdoc into an array like:
// array('type' => 'string', 'since' => '1.0')
$phpdocTags = ...;
return $phpdocTags;
}
} |
另外3个方法(guessMaxLength(),guessRequired(),guessPattern())返回的是带有选项值的ValueGuess实例。其构造器有2个参数:
选项的值;
所猜之值有多正确的“自信度”(使用Guess类中的常量)。
若猜为null则表示你认为这个选项不应该被设置。
你应该非常小心地使用guessPattern()方法。当类型是float时,你不能用它来决断这个浮点的min值或max值(比如,你希望一个浮点大于5,那么4.512313是无效的,不过length(4.512314) > length(5)却是有效的,进而匹配成功)。在这个例子中,参数的取值应该分别设为null和MEDIUM_CONFIDENCE。
你要做的最后一件事,是用addTypeGuesser()方法或addTypeGuessers()方法来注册你的自定义type guesser:
1 2 3 4 5 6 7 8 9 | use Symfony\Component\Form\Forms;
use Acme\Form\PHPDocTypeGuesser;
$formFactory = Forms::createFormFactoryBuilder()
// ...
->addTypeGuesser(new PHPDocTypeGuesser())
->getFormFactory();
// ... |
使用Symfony框架时,需要注册你的type guesser,并为它打上form.type_guesser标签。更多信息请阅读tag参考。
本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。