Validation 如何使用sfForm验证没有日期的日期?

Validation 如何使用sfForm验证没有日期的日期?,validation,forms,date,symfony1,Validation,Forms,Date,Symfony1,我正在使用symfony 1.4创建一个付款表单,我的表单有一个日期小部件,定义如下,以便用户可以选择其信用卡的到期日期: new sfWidgetFormDate(array( 'format' => '%month%/%year%', 'years' => array_combine(range(date('Y'), date('Y') + 5), range(date('Y'), date('Y') + 5)) 请注意,与大多数付款表单一样,格式中缺少%day% 现

我正在使用symfony 1.4创建一个付款表单,我的表单有一个日期小部件,定义如下,以便用户可以选择其信用卡的到期日期:

new sfWidgetFormDate(array(
  'format' => '%month%/%year%',
  'years'  => array_combine(range(date('Y'), date('Y') + 5), range(date('Y'), date('Y') + 5))
请注意,与大多数付款表单一样,格式中缺少%day%

现在我的问题是,sfValidatorDate要求“day”字段不能为空。为了解决这个问题,我使用回调创建了一个自定义验证器,它工作得很好:

public function validateExpirationDate($validator, $value)
{
  $value['day'] = '15';
  $dateValidator = new sfValidatorDate(array(
    'date_format' => '#(?P<day>\d{2})(?P<month>\d{2})(?P<year>\d{2})#',
    'required'    => false,
    'min'         => strtotime('first day of this month')));
  $dateValidator->clean($value);
  return $value;
}
公共函数validateExpirationDate($validator,$value)
{
$value['day']='15';
$dateValidator=新的sfValidatorDate(数组(
“日期格式”=>“#”(?P\d{2})(?P\d{2})(?P\d{2})#”,
“必需”=>false,
'min'=>strotime('本月第一天');
$dateValidator->clean($value);
返回$value;
}

我觉得可能有一个更简单的方法来实现这一点。你怎么认为?您是否已经以更干净的方式解决了此问题?

如何存储日期?如果您只是将月份和年份存储为整数或字符串,那么您可以选择两个小部件。但是如果您将其存储为datetime(timestamp),那么您仍然需要一个有效的日期。这意味着您需要自动将值指定给“天”(通常是每月的第一天或最后一天)


无需使用自定义验证类:只需重写传递给bind()方法的受污染值:


对于验证信用卡到期日,我使用了最简单的方法:

$post_data = $request->getParameter('my_form');
$post_data['card_exp']['day'] = 1; //sets the first day of the month
$this->form->bind($post_data);

希望这对某人有所帮助。

我在form类中首先解决了这个问题

    $year = range(date('Y'), date('Y') - 50);

    $this->widgetSchema['date'] = new sfWidgetFormDate(array(
      'format' => '%year%',
      'years' => array_combine($year, $year),
      'can_be_empty' => false
    ));
接下来

    public function bind(array $taintedValues = null){
      $taintedValues['date']['day'] = '01';
      $taintedValues['date']['month'] = '01';

      parent::bind($taintedValues);
    }

数据库中的字段是date类型date。

目前,我不存储它,但我会将它存储为将来的一个字段,很可能是一个字符串,因为我将它发送到的web服务只需要一个字符串。或者,如果我想用它来提醒我的用户,当他的信用卡过期时,可以作为时间戳。无论如何,我(和你的)configure方法中的代码会创建两个选择框。我想说的是,我希望在当前月份或更晚的时间内有一个有效日期。这是我们的两个代码所做的,但您的代码似乎更具可配置性,因此+1:)+1,这是imo的最佳解决方案。将逻辑保留在表单层,无需自定义验证。但您仍然可以确保一致的验证和存储。
    $year = range(date('Y'), date('Y') - 50);

    $this->widgetSchema['date'] = new sfWidgetFormDate(array(
      'format' => '%year%',
      'years' => array_combine($year, $year),
      'can_be_empty' => false
    ));
    public function bind(array $taintedValues = null){
      $taintedValues['date']['day'] = '01';
      $taintedValues['date']['month'] = '01';

      parent::bind($taintedValues);
    }