如何在 symfony2 验证器中允许空值
Posted
技术标签:
【中文标题】如何在 symfony2 验证器中允许空值【英文标题】:How to allow empty values in symfony2 validators 【发布时间】:2011-11-23 01:39:59 【问题描述】:我想仅在值不为空时对对象属性应用验证器。
现在标准的 symfony 行为:
class Entity
/**
* @ORM\Column(type="string", nullable=true)
* @Assert\Email()
*/
protected $email;
(...)
如果电子邮件为 null 或空字符串,该对象将不会通过验证,有没有办法告诉验证器断言为有效的空值,并且仅在字段有数据时验证?
PS 我知道我可以编写回调验证器,但是为每个字段编写回调只是为了拥有“allowEmpty”功能并不是那么好。
【问题讨论】:
【参考方案1】:您必须在 FormBuilder
类中为所有可选字段显式设置 'required' => false
。这是一段描述field type options的段落。
编辑。获得不少反对票。默认情况下,所有验证器将 null
值视为有效,除了 NotNull
和 NotEmpty
。两个都没有在问题中使用。问题隐含地是关于如何关闭默认打开的客户端required
属性。
【讨论】:
这不是正确的答案。 'required' 选项仅强制执行客户端验证。 @TyrionLannister 你确实是正确的。但是,除了具有NotNull()
和NotEmpty()
约束时,所有默认验证器都不会导致空值被视为无效。鉴于提问者没有这些限制,暗示问题出在客户端 html5 required
属性上。
@gilden 恕我直言,required
属性与批准的空值没有任何共同之处。它仅用于 HTML5 客户端验证,与验证(服务器端)完全无关。
@AndrzejOśmiałowski 绝对,请查看您上面的评论。这正是我所说的:)
如果他根本不知道实现它的正确方法是设置 NotNull 或 NotEmpty 约束怎么办?我发现这个解释很有趣。即便如此,我相信他会后悔当他尝试通过 XHR 发送带有 JSON 格式数据的表单数据时犯了多少错误,表单将被传递,您将一无所获。这正是我现在所面临的。这只是一定程度上的答案,而不是完整的答案。【参考方案2】:
如果我理解正确,您仅在输入值时才需要服务器端验证。我完全处于同样的情况。我只想在提供 URL 的情况下验证 URL。我遇到的最好方法是编写我自己的自定义验证类。您可以编写一个通用的自定义验证类。
我关注了这个链接https://symfony-docs-chs.readthedocs.org/en/2.0/cookbook/validation/custom_constraint.html,除了因为 symfony 的最新版本而做了一些更改。 这是实现
Acme\BundleNameBundle\Validator\Constraints\cstmUrl
namespace Acme\BundleNameBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints\Url;
/**
* @Annotation
*/
class CstmUrl extends Url
public $message = 'The URL "%string%" is not valid';
Acme\BundleNameBundle\Validator\Constraints\cstmUrlValidator
namespace Acme\BundleNameBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints\Url;
use Symfony\Component\Validator\Constraints\UrlValidator;
class CstmUrlValidator extends UrlValidator
public function validate($value, Constraint $constraint)
if(!$value || empty($value))
return true;
parent::validate($value, $constraint);
Validtion.yml
Acme\BundleNameBundle\Entity\Student:
Url:
- Acme\BundleNameBundle\Validator\Constraints\CstmUrl: ~
在 Controller 中只绑定你通常会做的约束
'constraints'=> new CstmUrl(array("message"=>"Invalid url provided"))
我相信还有其他更好的方法可以做到这一点,但现在我觉得这做得很好。
【讨论】:
【参考方案3】:字段类型猜测处理这个。 http://symfony.com/doc/current/book/forms.html#field-type-guessing
这取决于您的表单声明:“当您省略 add() 方法的第二个参数(或者如果您将 null 传递给它)时,“猜测”将被激活。如果您传递一个options 数组作为第三个参数(为上面的 dueDate 完成),这些选项将应用于猜测的字段。"
【讨论】:
【参考方案4】:以防万一其他人遇到同样的问题。我更喜欢通过在我的 Twig 模板中添加以下属性来亲自解决它:
form_row(form.<field>, 'required': false)
【讨论】:
我认为您不想在模板中硬编码。如果您想使用required
方法,请改用 gilden 的建议并将其添加到表单构建器中......
是的,在大多数情况下,我认为这将是一种更好的方法(这样属性验证要求会在其他模板中传播),但是在某些情况下(即简单的应用程序)将其放入 Twig 模板中并不是太可怕了:)【参考方案5】:
这是我实际发现的技巧:
https://github.com/symfony/symfony/issues/5906
您需要编写一个什么都不做的数据转换器,然后将其添加到您的字段中。 之后,只需调用 submit() 方法,并将第二个参数设置为 false。
请注意,Symfony 2.3 没问题。
【讨论】:
【参考方案6】:设置required
选项不是解决方案:
另请注意,将 required 选项设置为 true 不会导致应用服务器端验证。换句话说,如果用户为该字段提交了一个空白值(例如,使用旧的浏览器或 Web 服务),它将被接受为有效值,除非您使用 Symfony 的 NotBlank 或 NotNull 验证约束。
http://symfony.com/doc/current/book/forms.html#field-type-options
对于我的自定义验证器,我添加了一个
if (null == $value)
return true;
到isValid()
方法。但是,我不确定标准验证器类的最佳方式是什么。
【讨论】:
这应该是接受的答案,因为接受的答案只适用于简单字段,不适用于嵌入式类型字段以上是关于如何在 symfony2 验证器中允许空值的主要内容,如果未能解决你的问题,请参考以下文章