【问题标题】:Field is not a valid field of the entity - DoctrineEncryptBundle Symfony字段不是实体的有效字段 - DoctrineEncryptBundle Symfony
【发布时间】:2015-09-22 14:23:53
【问题描述】:

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

我已经配置并安装了bundle,并在Entity中导入了@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.

我做错了什么?

【问题讨论】:

  • 我不确定,但我认为由于 FOSUser 在 BaseUser 中定义了 firstName,因此您的和他们的可能会混淆
  • 我检查并没有在用户中定义名字。所以这不是问题。不过谢谢你的建议。
  • 也许它应该被保护而不是私有的?我只是在这里猜测

标签: php forms symfony encryption doctrine-orm


【解决方案1】:

我在 Doctrine/Zend 中使用a noticeably similar extension,我遇到了同样的问题。我注意到它发生在任何时候:

  1. 我标记了一个字段@Encrypted(例如names
  2. 我将未加密的值留在了数据库中(例如bob
  3. 我在未更改未加密值的情况下写入该表行(例如(id, bob, x, y, z)

我在此处将问题追溯到 DoctrineEncryptSubscriber.php(在 vmelnik-ukraine/DoctrineEncryptBundle 中相同)的源代码:

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();
            $args->setNewValue($propName, $this->encryptor->encrypt($args->getNewValue($propName))); // this line is the problem
        }
    }
}

$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)));
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-21
    • 2018-06-25
    相关资源
    最近更新 更多