【问题标题】:Validating decimals in symfony 2在 symfony 2 中验证小数
【发布时间】:2012-01-23 22:42:13
【问题描述】:

我使用 Doctrine 将 symfony2 实体映射到一个表。属性之一是:

/**
 * @var decimal $price
 *
 * @ORM\Column(name="price", type="decimal", nullable=false)
 */
private $price;

什么Assert 可以满足我的要求,即$price 应该是一个有效的小数?

如果我保持原样,那么将字符串 foo 作为十进制值传递会导致验证错误,而传递字符串 NaN 会通过验证,因为字符串 NaN 被映射为 float(NaN),因此被视为一个有效的十进制值。

有什么解决方法吗?

Symfony 开发团队保证这不是问题:https://github.com/symfony/symfony/issues/3161

好吧,如果不是 - 那么可能有一个解决方案来验证它。有什么想法吗?

【问题讨论】:

  • 如果有人需要在验证中允许“NaN”怎么办?只需编写您自己的转换器 'non_nan_decimal' ;)
  • @meze: omg )) 我需要做多少步骤才能从操作方法中获取基本示例? ;-)
  • 你说 'NaN' 是十进制的有效值,然后希望它被转换为 0,因为你想要这样;)
  • @meze:我说根据验证器是有效的。对我(和数据库)来说 - 它不是有效值
  • 我没有看到任何关于教义 orm 的问题,它为价格字段设置了空值。另外,你不能在 setter 中标准化价格吗?

标签: php symfony


【解决方案1】:

通过查看 Symfony 文档,没有内置的小数验证器。您可以使用回调验证器,或者更好的是您可以创建自己的自定义验证器,如本文describes here

至于实际验证,我会使用is_numericis_float 的组合来检查。有一些使用正则表达式的方法,但我认为如果值满足is_numericis_float 检查,那么您可以放心地假定它是有效的小数(或整数)。

编辑:

也许最好的解决方案是将小数验证为字符串。比如……

$stringDecimal = strval($decimalValue);
return (preg_match(/[0-9]+(\.[0-9][0-9]?)?/, $stringDecimal) !== 0);

虽然这并不完美(您可以轻松通过 '1.15adowadjaow' 并且它会验证),但它是您所追求的基础。将上述正则表达式与搜索除 0-9、句号或逗号以外的任何内容(取决于您是否要满足欧洲十进制格式)的内容相结合。

【讨论】:

  • float(NaN) 通过 is_floatis_numeric
  • 先将其转换为字符串并检查该值是否不等于 'NaN' 怎么样?
  • @zerkms 你是对的,与验证相比,强制转换更像是一个清理过程,更合适的方法可能是调用 strval() 然后使用正则表达式验证字符串,我会更新我的回答
  • 太奇怪了 :-S 想知道 SF2 中没有任何内置内容 :-S
  • @zerkms 我同意,很惊讶没有开箱即用的东西......我想我会在 github 上将其报告为问题
【解决方案2】:

您可以尝试使用 custom validator 来检查该字符串。

【讨论】:

  • 是的,我知道这种可能性,但令人作呕的是,他们提供了一种无法检查其是否有效的类型
  • "只检查那个字符串。" - 这实际上是一个糟糕的解决方案。我不可能知道任何魔术字符串。我想检查数据是否有效,而不是检查数据是否无效
【解决方案3】:

如果您使用表单类型进行记录

        ->add(
            'amount',
            'text', change text to number and it will be validated 
            [
                'required' => true
            ]
        )

或者你可以使用范围断言

  • @Assert\Range(min=0)

它将验证它应该是数字

【讨论】:

  • float(NaN) 不是一个数字吗?加上min=0 有不同的语义。
【解决方案4】:

您可以简单地使用@Assert\Type(type="Numeric")。在 symfony 3.4 中测试,但我认为它也适用于以前的版本。例如

 /**
 * @var float
 *
 * @ORM\Column(name="cost", type="decimal", precision=10, scale=4)
 * @Assert\Type(type="Numeric")
 */
private $cost;

谢谢!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-30
    • 2015-09-16
    • 1970-01-01
    • 2023-03-06
    • 2014-08-16
    • 2011-11-27
    • 2018-05-10
    相关资源
    最近更新 更多