【问题标题】:Symfony form values do not bindSymfony 表单值不绑定
【发布时间】:2012-08-05 23:35:45
【问题描述】:

我正在使用 Symfony 1.4 表单作为一个简单的登录模块。该表单非常基本,其代码如下所示:

<?php 

class LoginForm extends sfFormSymfony 
{
 public function configure()
 {
  $this->setWidgets( 
         array('username' => new sfWidgetFormInputText(),
               'password' => new sfWidgetFormInputPassword(),));
              // 'remember_me' => new sfWidgetFormSelectCheckbox(array('choices'=>array('true'=>''))),));

   $this->widgetSchema->setNameFormat('login[%s]');
   $this->setValidators(array(
         'username' =>  new sfValidatorString(array('required'=>true)),        
         'password' =>  new sfValidatorString(array('required'=>true)),
     ));
 }

}

表单按预期在模板页面中呈现良好。仅供参考,我使用 $form['username']->render 方法来单独渲染我喜欢的方法,而不是回显表单。

在发布(已识别)后,我将值绑定到如下形式:

$this->form->bind($request->getParameter('login')); 

但是,它不符合条件

$this->form->isValid();

这两个字段都没有留空并且凭据正确,所以这对我来说似乎更阴险。

在执行 var_dump($this->form->getValues());它返回一个空数组,我认为这意味着这些值没有被检索或绑定。

谁能发现我可能搞砸的地方?

谢谢

【问题讨论】:

  • 如果你转储$request-&gt;getParameter('login'),你会得到预期值吗?
  • 是的,就这么做了,它转储了应有的用户名和密码值
  • 您是否也获得了 csrf 令牌?
  • 不,没有转储 csrf 令牌
  • 这就是您的表单无效的原因(如果您启用了 csrf 保护)。确保通过模板中的$form-&gt;renderHiddenFields()$form["_csrf_token"]-&gt;render() 呈现字段。

标签: symfony1 symfony-1.4 symfony-forms


【解决方案1】:

从 symfony 1.3 开始,默认启用 csrf 保护。这意味着您的所有表单都会获得一个 csrf 令牌字段,默认命名为 _csrf_token - 这是一个隐藏字段,对您的会话和给定表单类型来说是唯一的。

如果您不与表单的其余部分一起呈现和提交此字段,它将无效 - 它检测到 csrf 攻击,所以这种方式很好。

简短的解决方法是渲染令牌字段:

echo $form["_csrf_token"]->render();

但更好的方法是一次性渲染所有隐藏字段(我通常在提交按钮旁边这样做):

echo $form->renderHiddenFields();

【讨论】:

    【解决方案2】:

    如果你真的需要,你可以使用一点 sn-p 来显示如下错误:

    foreach ($this->getErrorSchema() as $field => $error) {
    
        if ($error instanceof sfValidatorErrorSchema) {
            foreach ($error as $field => $error) break;
        }
    
        echo $field . ' => ' . $error; // e.g. "Field name" => "Error message".
    
    }
    

    【讨论】:

      【解决方案3】:

      @Maerlyn 解决了这个问题。供将来参考:

      表单字段是单独呈现的,而不是使用 vanilla echo $form。因此,我没有渲染应该完成的 $form['_csrf_token']->render() 。因此登录失败。渲染 csrf_token 字段,你就可以开始了。

      【讨论】:

      • 请让我知道这是否是向通过 cmets 回答问题的人表示赞赏的适当方式......谢谢!
      • 很高兴我能帮上忙。我将添加一个您可以接受的答案作为解决方案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-16
      • 1970-01-01
      • 1970-01-01
      • 2015-05-13
      • 1970-01-01
      相关资源
      最近更新 更多