Php 字段不是实体的有效字段-DoctrineEncryptBundle Symfony

Php 字段不是实体的有效字段-DoctrineEncryptBundle Symfony,php,forms,symfony,encryption,doctrine-orm,Php,Forms,Symfony,Encryption,Doctrine Orm,我的应用程序中有一个注册表,我想使用用于Symfony的vmelnik ukraine/DoctrineEncryptBundle对数据进行加密。 登记表来自FOSUserBundle 我已经配置并安装了捆绑包,并在实体中导入了@Encrypted注释,如下所示: namespace AppBundle\Entity; use Doctrine\ORM\Mapping as ORM; use FOS\UserBundle\Model\User as BaseUser; use Symfony\

我的应用程序中有一个注册表,我想使用用于Symfony的vmelnik ukraine/DoctrineEncryptBundle对数据进行加密。 登记表来自FOSUserBundle

我已经配置并安装了捆绑包,并在实体中导入了@Encrypted注释,如下所示:

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
use Symfony\Component\Validator\Constraints as Assert;
use VMelnik\DoctrineEncryptBundle\Configuration\Encrypted;

    /**
    * Developer
    *
    * @ORM\Entity
    * @ORM\Table(name="fos_user")
    */
    class Developer extends BaseUser
    {
       ...

       /**
        * @var string
        * @ORM\Column(name="firstname", type="string", length=255)
        * @Encrypted
        * @Assert\Length(
        *      min = 2,
        *      max = 50,
        *      minMessage = "profile.register.notification.name.too-short",
        *      maxMessage = "profile.register.notification.name.too-long"
        * )
        */
       private $firstname;
但是现在,当提交表单时,我得到以下错误:

Field "firstname" is not a valid field of the entity "AppBundle\Entity\Developer" in PreUpdateEventArgs.
我做错了什么

我在使用Doctrine/Zend时遇到了同样的问题。我注意到每当:

  • 我将一个字段标记为@Encrypted(例如,
    名称
  • 我将未加密的值留在数据库中(例如,
    bob
  • 我在不更改未加密值的情况下写入了该表行(例如
    (id,bob,x,y,z)
  • 我将问题追溯到DoctrineEncryptSubscriber.php的源代码(在vmelnik乌克兰/DoctrineEncryptBundle中是相同的):

    $args->setNewValue(…)
    调用
    assertValidField($field)
    ,检查@Encrypted字段是否在
    entityChangeSet
    中。。。这不是因为我没有做任何改变。所以它抛出了一个异常。如果数据库中的值已经加密,则不会发生这种情况,因为
    entityChangeset
    对旧值具有加密值,对新值具有明文

    我使用的补丁程序仅在我们实际更改字段时调用
    setNewValue()
    ,如下所示:

    public function preUpdate(PreUpdateEventArgs $args)
    {
        $reflectionClass = new ReflectionClass($args->getEntity());
        $properties = $reflectionClass->getProperties();
        foreach ($properties as $refProperty) {
            if ($this->annReader->getPropertyAnnotation($refProperty, self::ENCRYPTED_ANN_NAME)) {
                $propName = $refProperty->getName();
                if ($args->hasChangedField($propName)) {
                    $args->setNewValue($propName, $this->encryptor->encrypt($args->getNewValue($propName)));
                }
            }
        }
    }
    

    我不确定,但我认为因为FOSUser在BaseUser中定义了firstName,所以您的和他们的RSI检查和firstName在User中没有定义之间可能会有混淆。所以这不是问题所在。但是谢谢你的建议。也许它应该被保护而不是隐私?我只是突然猜出来的
    public function preUpdate(PreUpdateEventArgs $args)
    {
        $reflectionClass = new ReflectionClass($args->getEntity());
        $properties = $reflectionClass->getProperties();
        foreach ($properties as $refProperty) {
            if ($this->annReader->getPropertyAnnotation($refProperty, self::ENCRYPTED_ANN_NAME)) {
                $propName = $refProperty->getName();
                if ($args->hasChangedField($propName)) {
                    $args->setNewValue($propName, $this->encryptor->encrypt($args->getNewValue($propName)));
                }
            }
        }
    }