问题是您在控制密码之前将表单绑定到用户对象。
让我们分析一下您的代码片段。
请执行下列操作
$user = $this->get('security.context')->getToken()->getUser();
会将现有用户加载到用户对象中。
现在,您使用该数据“构建”一个表单,如果收到帖子,您将把发布的数据放入前一个对象中
$userForm = $this->createForm(new UserFormType(), $user);
if ($request->getMethod() == 'POST') {
$userForm->bindRequest($request);
所以,到bindRequest
您已经丢失了之前的密码进入物体(显然还没有进入数据库)如果留空。从现在开始的每一个控制都是没有用的。
这种情况下的解决方案是直接手动验证表单字段的值$request
对象,然后将其绑定到底层对象。
您可以使用这个简单的代码片段来完成此操作
$postedValues = $request->request->get('formName');
现在您必须验证密码值是否已填写
if($postedValues['plainPassword']) { ... }
where plainPassword
我想是我们感兴趣的领域的名称。
If you find that this field contain a value (else branch) you haven't to do anything.
Otherwise you have to retrieve original password from User Object and set it into $request
corrisponding value.
(update) Otherwise you may retrieve password from User Object but since that password is stored with an hased valued, you can't put it into the $request
object because it will suffer from hashing again.
What you could do - i suppose - is an array_pop http://php.net/manual/en/function.array-pop.php directly into $request
object and put away the field that messes all the things up (plainPassword)
Now that you had done those things, you can bind posted data to underlying object.
另一个解决方案(可能更好,因为您将一些业务逻辑从控制器中移开)是使用prePersist
hook,但概念上更先进。如果您想探索该解决方案,您可以阅读以下内容表单事件 http://symfony.com/doc/current/cookbook/form/dynamic_form_generation.html