【问题标题】:Symfony form validation of integer field整数字段的 Symfony 表单验证
【发布时间】:2015-04-21 17:54:36
【问题描述】:

我正在尝试对整数使用类型验证规则,但它失败并出现一些警告。

这是我的表格

class BusinessType extends AbstractType {
    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder->add('business_number', 'integer', array(
            'required' => false,
        ));
    }
}

这是我的验证规则

My\Bundle\Entity\Business:
    properties:
        business_number:
            - Type:
                type: integer

所以没有什么奢侈的!

但我收到以下错误

未捕获的 PHP 异常 Symfony\Component\Debug\Exception\ContextErrorException:“警告:NumberFormatter::parse(): Number parsing failed”

我已经找到了解决 here 的方法,但这样做感觉不对。如果没有其他解决方案,我会这样做,但我更愿意避免它。

我知道这是 Symfony 早期版本中的一个已知错误,但它应该被修复。见here

那么有没有办法可以使用类型验证?如果是这样,我错过了什么?

编辑 1

我正在使用 Symfony 2.6.6

编辑 2

如果我的值以数字开头(如 123dd),即使我自定义了错误消息,我也会收到以下错误消息

此值无效。

但如果我的值以其他东西开头,我就有上述错误。

编辑 3

我需要存储的最长值是 9 位数。所以整数应该可以正常工作。

编辑 4

这里是bug report

【问题讨论】:

  • 您是要输入电话号码还是整数?电话号码存储为整数是一件很糟糕的事情。你必须去掉破折号和可能有用的信息(扩展呢?我如何将它表示为整数?)你应该使用带有正则表达式验证的文本表单类型,或者想出一个自定义表单类型,这样你就可以利用 HTML5 tel 输入类型。
  • 这是一个我需要存储的整数。这不是电话号码。
  • 您在提交表单并将business_number留空时是否收到此错误?
  • 不,空白或为空时它可以正常工作。
  • 应该注意的是,您链接到 Symfony2 存储库的 PR 是针对 number Form Type,而不是 integer,尽管 IntegerToLocalizedStringTransformer 扩展了 NumberToLocalizedStringTransformer。您可以尝试改用number 表单类型吗?

标签: forms validation symfony


【解决方案1】:

问题在于integer 和/或number Symfony 表单类型在将值存储到表单之前使用了Symfony\Component\Intl\NumberFormatter\NumberFormatter::parse method。该方法的内容如下(从 Symfony 2.6.6 开始):

public function parse($value, $type = self::TYPE_DOUBLE, &$position = 0)
{
    if ($type == self::TYPE_DEFAULT || $type == self::TYPE_CURRENCY) {
        trigger_error(__METHOD__.'(): Unsupported format type '.$type, \E_USER_WARNING);
        return false;
    }
    preg_match('/^([^0-9\-\.]{0,})(.*)/', $value, $matches);
    // Any string before the numeric value causes error in the parsing
    if (isset($matches[1]) && !empty($matches[1])) {
        IntlGlobals::setError(IntlGlobals::U_PARSE_ERROR, 'Number parsing failed');
        $this->errorCode = IntlGlobals::getErrorCode();
        $this->errorMessage = IntlGlobals::getErrorMessage();
        $position = 0;
        return false;
    }
    preg_match('/^[0-9\-\.\,]*/', $value, $matches);
    $value = preg_replace('/[^0-9\.\-]/', '', $matches[0]);
    $value = $this->convertValueDataType($value, $type);
    $position = strlen($matches[0]);
    // behave like the intl extension
    $this->resetError();
    return $value;
}

尤其是这部分:

preg_match('/^([^0-9\-\.]{0,})(.*)/', $value, $matches);
// Any string before the numeric value causes error in the parsing
if (isset($matches[1]) && !empty($matches[1])) {
    IntlGlobals::setError(IntlGlobals::U_PARSE_ERROR, 'Number parsing failed');

// ...

将导致任何以字符串开头的格式错误的条目引发异常。

不幸的是,更改验证规则将无济于事,因为此解析是在验证发生之前运行的。

您唯一的解决方法将是您已链接的解决方法,并提交错误报告,直到问题得到解决。 current master branch doesn't have an update to this file,目前尚不清楚问题是否在其他地方得到解决(需要进一步研究)。

前端验证也有帮助(例如,HTML5 numberinteger 类型的内置验证会导致大多数浏览器在提交给 Symfony 之前阻止您)。

【讨论】:

  • 谢谢。我会做一个错误报告。
  • @A.D.请在此处链接。我可能会在空闲时间进行更多研究。
  • 我在原始消息中添加了错误报告的链接
猜你喜欢
  • 2015-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-10
  • 2020-07-25
  • 1970-01-01
相关资源
最近更新 更多