在CakePHP中验证和转换十进制值

在CakePHP中验证和转换十进制值,php,validation,cakephp,decimal,Php,Validation,Cakephp,Decimal,我正在用CakePHP开发一个处理货币价值的应用程序。客户端希望数字具有自定义格式,如1.275,34,即整数部分用点作为分隔符,小数部分用逗号作为分隔符 我想知道最好的管理方法是什么,因为我需要做两件基本的事情: 根据自定义格式验证表单中写入的值 根据MySQL的列数据类型所期望的格式转换这些值(decimal(18,2)在本例中,上述示例中为1275.34) 我想我有这些选项,但我对任何一个都不太满意,因为有几个模型使用这种自定义格式,这意味着要复制一些代码: 在调用$this->Mode

我正在用CakePHP开发一个处理货币价值的应用程序。客户端希望数字具有自定义格式,如
1.275,34
,即整数部分用点作为分隔符,小数部分用逗号作为分隔符

我想知道最好的管理方法是什么,因为我需要做两件基本的事情:

  • 根据自定义格式验证表单中写入的值
  • 根据MySQL的列数据类型所期望的格式转换这些值(
    decimal(18,2)
    在本例中,上述示例中为
    1275.34
  • 我想我有这些选项,但我对任何一个都不太满意,因为有几个模型使用这种自定义格式,这意味着要复制一些代码:

    • 在调用
      $this->Model->save()
      (可能使用组件)之前,验证并转换控制器中的值
    • 使用模型中的自定义规则(
      var$Validate
      array)验证数据并转换它们,可能使用行为
    你推荐什么?有没有其他方法来处理这个问题


    谢谢

    您可以使用PHPs
    number\u format()
    以任意方式对其进行格式化:

    至于将其挂接,如果希望在模型中执行转换,可以使用
    beforeSave()
    afterFind()
    回调来执行转换

    我建议您保留一个额外的字段,该字段在使用上述回调进行查找操作后填充到模型中,以便您始终可以使用该字段,并且在意外尝试保存该字段时不会出错

    同时 您可以使用virtualFields(可从cakePHP 1.3获得)创建一个字段,该字段在每次查找时由DB填充。您可以使用MySQLs字符串格式来实现这一点

    虚拟字段:

    MySQL字符串:

    例如

    var $virtualFields = array(
        'formatted' => 'FORMAT(12332.1,2)' // would output 12,332.10
    );
    
    “1.234,56”格式是欧洲货币格式,因此您最好让整个应用程序使用这种格式。您需要做的是使用
    setlocale(LC\u monetary,$locale)
    设置应用程序的货币区域设置。例如:

    setlocale(LC_MONETARY, 'it_IT');
    

    然后,使用适当的格式设置货币字符串,并使用
    Model::beforeValidate()
    回调在验证之前对任何货币输入进行处理,以便可以根据标准十进制格式进行验证

    我喜欢这种方法,因为它避免了我自己编写转换代码。但同样的问题也出现了:验证时如何使用货币区域设置?在哪里?每当用户在表单中写入错误值时,我都会通知用户在这种情况下,我会在
    beforeValidate
    回调中处理输入数据,而不是在
    beforeSave
    中。我已经更新了我的答案。如果我想根据数据库的数据类型验证数据,那就可以了。但我想根据自定义格式进行验证。最后,我使用
    beforeSave
    方法来处理定制数据,并使用
    afterFind
    方法相应地显示它。下一步是使用行为进行重构,但您的回答为我指明了正确的方向。我尽量不使用virtualFields,因为据我所知,它依赖于数据库