Symfony2 在仅包含某些内容时验证文本输入
Symfony2 validate text input when containing something only
我想验证一个包含下拉菜单和文本输入字段的表单。
用户可以从下拉菜单中选择项目。如果他想创建一个新项目,他可以使用下拉菜单旁边的文本输入字段。
这是我的上传类型:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->setAction('upload')
->setMethod('POST')
// project name dropdown menu
->add('projectname', 'choice' , array(
'label' => 'upload_project_label',
'choices' => $this->projects,
'attr' => array(
'class' => 'form-control some',
'required' => 'true'
)
))
// newprojectname text input
->add('newprojectname', 'text', array(
'label' => false,
'attr' => array(
'class' => 'form-control',
'required' => false,
'placeholder' => 'upload_newprojectname_placeholder'
)
)
)
...
这是我上传实体的片段:
/**
* @ORM\Column(type="text")
*
* @var string $projectname
* @Assert\NotBlank()
*/
protected $projectname;
/**
* @ORM\Column(type="text")
*
* @var string $newprojectname
* @Assert\Length(
* min = 3,
* max = 7,
* minMessage = "min message",
* maxMessage = "max message"
* )
*/
protected $newprojectname;
我的问题是是否可以查询以检查是否设置了字段 newproject(即输入了字符串)?如果是这样,让 Assert 注释完成它的工作。
这可以通过多种方式完成,所有方式都可能满足您的要求。
- 使用 custom callback - 这是最快最直接的方法
- 使用 expression validator - 很多人对在 PHP 中嵌入元语言有疑问,这是完全有效的,但这是另一种快速的做事方式
- 使用group sequences, specifically the group sequence provider功能
您选择哪一个取决于您,但回调是一个快速简单的起点,如果您的验证约束变得更加复杂,您可以在此基础上进行构建。
这是作为自定义回调验证的建议解决方案的代码块。
我不得不在我的上传实体中添加另一个函数,如下所示:
use Symfony\Component\Validator\Context\ExecutionContextInterface;
/**
* Function holds custom validation for fields in import/upload form
* @Assert\Callback
* @param ExecutionContextInterface $context
*/
public function validate(ExecutionContextInterface $context)
{
// check new project name
$newProjectName = $this->getNewprojectname();
if(!empty($newProjectName)) {
// letters only
$pattern = '/[a-zA-Z]/';
if($this->isPatternWrong($newProjectName, $pattern)) {
$context
->buildViolation('Please use letters only.')
->atPath('newprojectname')
->addViolation();
}
// text max. 7 digits
$maxlength = 7;
if($this->isStringTooLong($newProjectName, $maxlength)) {
$context
->buildViolation('Max. length 7 digits.')
->atPath('newprojectname')
->addViolation();
}
}
}
private function isPatternWrong($string, $pattern)
{
$result = preg_match($pattern, $string);
if($result === 0) {
return true;
}
return false;
}
private function isStringTooLong($string, $length)
{
if(strlen($string) > $length) {
return true;
}
return false;
}
我想验证一个包含下拉菜单和文本输入字段的表单。
用户可以从下拉菜单中选择项目。如果他想创建一个新项目,他可以使用下拉菜单旁边的文本输入字段。
这是我的上传类型:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->setAction('upload')
->setMethod('POST')
// project name dropdown menu
->add('projectname', 'choice' , array(
'label' => 'upload_project_label',
'choices' => $this->projects,
'attr' => array(
'class' => 'form-control some',
'required' => 'true'
)
))
// newprojectname text input
->add('newprojectname', 'text', array(
'label' => false,
'attr' => array(
'class' => 'form-control',
'required' => false,
'placeholder' => 'upload_newprojectname_placeholder'
)
)
)
...
这是我上传实体的片段:
/**
* @ORM\Column(type="text")
*
* @var string $projectname
* @Assert\NotBlank()
*/
protected $projectname;
/**
* @ORM\Column(type="text")
*
* @var string $newprojectname
* @Assert\Length(
* min = 3,
* max = 7,
* minMessage = "min message",
* maxMessage = "max message"
* )
*/
protected $newprojectname;
我的问题是是否可以查询以检查是否设置了字段 newproject(即输入了字符串)?如果是这样,让 Assert 注释完成它的工作。
这可以通过多种方式完成,所有方式都可能满足您的要求。
- 使用 custom callback - 这是最快最直接的方法
- 使用 expression validator - 很多人对在 PHP 中嵌入元语言有疑问,这是完全有效的,但这是另一种快速的做事方式
- 使用group sequences, specifically the group sequence provider功能
您选择哪一个取决于您,但回调是一个快速简单的起点,如果您的验证约束变得更加复杂,您可以在此基础上进行构建。
这是作为自定义回调验证的建议解决方案的代码块。
我不得不在我的上传实体中添加另一个函数,如下所示:
use Symfony\Component\Validator\Context\ExecutionContextInterface;
/**
* Function holds custom validation for fields in import/upload form
* @Assert\Callback
* @param ExecutionContextInterface $context
*/
public function validate(ExecutionContextInterface $context)
{
// check new project name
$newProjectName = $this->getNewprojectname();
if(!empty($newProjectName)) {
// letters only
$pattern = '/[a-zA-Z]/';
if($this->isPatternWrong($newProjectName, $pattern)) {
$context
->buildViolation('Please use letters only.')
->atPath('newprojectname')
->addViolation();
}
// text max. 7 digits
$maxlength = 7;
if($this->isStringTooLong($newProjectName, $maxlength)) {
$context
->buildViolation('Max. length 7 digits.')
->atPath('newprojectname')
->addViolation();
}
}
}
private function isPatternWrong($string, $pattern)
{
$result = preg_match($pattern, $string);
if($result === 0) {
return true;
}
return false;
}
private function isStringTooLong($string, $length)
{
if(strlen($string) > $length) {
return true;
}
return false;
}