Symfony2进行表单验证,而不是数据库验证(Symfony2 do Form validation rather then database validation)

我有一个CreditCard实体,现在我想在实体中对此进行基本验证,例如:

/** * @ORM\Column(name="number", type="string", length=255) * @Assert\CardScheme( * schemes={"VISA", "MASTERCARD", "DISCOVER", "DINERS"}, * message="The card number is not valid, we only support Visa, Mastercard, Discover og Diners club." * ) */ private $number;

但问题是我存储了加密的卡号。

他们最终看起来有很多不同,在我的表单类型中,我这样做是为了加密值并删除所有不必要的东西。

public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('number') ->add('expiration_year', 'choice', array( 'required' => true, 'choices' => $this->buildYearChoices() )) ->add('expiration_month', 'choice', array( 'required' => true, 'choices' => array( '01' => '01', '02' => '02', '03' => '03', '04' => '04', '05' => '05', '06' => '06', '07' => '07', '08' => '08', '09' => '09', '10' => '10', '11' => '11', '12' => '12', ) )) ->add('cvc', 'text'); $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) { $data = $event->getData(); $number = preg_replace("/[^0-9]/", "", $data['number']); $data['number'] = $number; $event->setData($data); }); $builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) { $credit_card = $event->getData(); $number = $credit_card->getNumber(); $customer_helper = $this->container->get('customer_helper'); $crypt = $customer_helper->encryptCreditCardNumber($number); $credit_card->setNumber($crypt); $event->setData($credit_card); }); }

即使我知道表单验证是在pre_submit上执行的,但是当我在SUBMIT上对它进行加密时,我仍然会收到验证错误

编辑:加密和解密emthods:

public function encryptCreditCardNumber($plaintext) { $ivSize = mcrypt_get_iv_size(self::CIPHER, self::MODE); //Gets the size of the IV belonging to a specific cipher/mode combination. $iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_RANDOM); //Creates an initialization vector (IV) from a random source. $ciphertext = mcrypt_encrypt(self::CIPHER, $this->container->getParameter('cc_encryption_key'), $plaintext, self::MODE, $iv); //Encrypts the data and returns it. return base64_encode($iv.$ciphertext); //Encode Base 64 } public function decryptCreditCardNumber($ciphertext) { $ciphertext = base64_decode($ciphertext); //Decode Base 64 $ivSize = mcrypt_get_iv_size(self::CIPHER, self::MODE); //Gets the size of the IV belonging to a specific cipher/mode combination. if (strlen($ciphertext) < $ivSize) { throw new Exception('Missing initialization vector'); } $iv = substr($ciphertext, 0, $ivSize); $ciphertext = substr($ciphertext, $ivSize); $plaintext = mcrypt_decrypt(self::CIPHER, $this->container->getParameter('cc_encryption_key'), $ciphertext, self::MODE, $iv); //Decrypts the data and returns it. return rtrim($plaintext, "\0"); }

i have a CreditCard entity, now i want to perform basic validation on this, in the entity, such as:

/** * @ORM\Column(name="number", type="string", length=255) * @Assert\CardScheme( * schemes={"VISA", "MASTERCARD", "DISCOVER", "DINERS"}, * message="The card number is not valid, we only support Visa, Mastercard, Discover og Diners club." * ) */ private $number;

But the issue is that i am storing the card numbers encrypted.

They end up looking a whole lot different, and in my form type, i do this to encrypt the values and remove all the uneccesary stuff.

public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('number') ->add('expiration_year', 'choice', array( 'required' => true, 'choices' => $this->buildYearChoices() )) ->add('expiration_month', 'choice', array( 'required' => true, 'choices' => array( '01' => '01', '02' => '02', '03' => '03', '04' => '04', '05' => '05', '06' => '06', '07' => '07', '08' => '08', '09' => '09', '10' => '10', '11' => '11', '12' => '12', ) )) ->add('cvc', 'text'); $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) { $data = $event->getData(); $number = preg_replace("/[^0-9]/", "", $data['number']); $data['number'] = $number; $event->setData($data); }); $builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) { $credit_card = $event->getData(); $number = $credit_card->getNumber(); $customer_helper = $this->container->get('customer_helper'); $crypt = $customer_helper->encryptCreditCardNumber($number); $credit_card->setNumber($crypt); $event->setData($credit_card); }); }

Even tho i know the form validation is performed pre_submit, i stil get a validation error, when i encrypt it on SUBMIT instead

EDIT: Encrypt and decrypt emthods:

public function encryptCreditCardNumber($plaintext) { $ivSize = mcrypt_get_iv_size(self::CIPHER, self::MODE); //Gets the size of the IV belonging to a specific cipher/mode combination. $iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_RANDOM); //Creates an initialization vector (IV) from a random source. $ciphertext = mcrypt_encrypt(self::CIPHER, $this->container->getParameter('cc_encryption_key'), $plaintext, self::MODE, $iv); //Encrypts the data and returns it. return base64_encode($iv.$ciphertext); //Encode Base 64 } public function decryptCreditCardNumber($ciphertext) { $ciphertext = base64_decode($ciphertext); //Decode Base 64 $ivSize = mcrypt_get_iv_size(self::CIPHER, self::MODE); //Gets the size of the IV belonging to a specific cipher/mode combination. if (strlen($ciphertext) < $ivSize) { throw new Exception('Missing initialization vector'); } $iv = substr($ciphertext, 0, $ivSize); $ciphertext = substr($ciphertext, $ivSize); $plaintext = mcrypt_decrypt(self::CIPHER, $this->container->getParameter('cc_encryption_key'), $ciphertext, self::MODE, $iv); //Decrypts the data and returns it. return rtrim($plaintext, "\0"); }

最满意答案

您可以捕获prePersist事件prePersist和preUpdate以便在运行时将普通代码替换为加密代码(在保存数据之前,在表单验证之后)。

要解密它,您可以使用postLoad 。

更多关于教义事件的信息在这里 。

请注意,学说事件与表单事件不同,不会干扰表单或验证(甚至可能根本没有表单)。

编辑:注入密钥

每当您需要将静态信息注入实体(例如参数或函数)时,请使用依赖注入。

如果你有一个bundle,请转到DependencyInjection文件夹并编辑Configuration.php文件(或者是另一个文件?我现在不记得了)。

您想要找到的是使用load方法加载参数的方法。

在此之后,从配置中获取所需的参数,并将其设置为类的静态成员,如下所示:

MyEntity::$secretKey = $configuration->getParameter('secretkey');

在实体内部,只需仔细阅读以下信息:

self::$secretKey

我把它从头顶上写下来,所以很多不准确的东西都可以插入。必要时纠正。 关键在于静态注入参数,如上所示。

You can catch the doctrine events prePersist and preUpdate to replace the plain code with the encrypted one on the fly (right before persisting the data, well after form validation).

To decrypt it, you can use postLoad.

More about doctrine events is here.

Note that the doctrine events are different from the form events and do not interfere with the form or validation (there might even not be a form at all).

EDIT: Inject key

Whenever you need to inject static information into an entity, such as a parameter or a function, use dependency injection.

If you have a bundle, go to the DependencyInjection folder and edit the Configuration.php file (or was it the other one? I don't remember now).

What you want to find is the method that loads the parameters with the load method.

Right after that, fetch the desired parameter from the configuration and set it in a static member of the class with something like this:

MyEntity::$secretKey = $configuration->getParameter('secretkey');

Inside the entity just peruse the information with:

self::$secretKey

I write this out of the top of my head, so many inaccuracies may have slipped in. Correct where necessary. The point is all about injecting the parameter statically as shown above.

Symfony2进行表单验证,而不是数据库验证(Symfony2 do Form validation rather then database validation)

我有一个CreditCard实体,现在我想在实体中对此进行基本验证,例如:

/** * @ORM\Column(name="number", type="string", length=255) * @Assert\CardScheme( * schemes={"VISA", "MASTERCARD", "DISCOVER", "DINERS"}, * message="The card number is not valid, we only support Visa, Mastercard, Discover og Diners club." * ) */ private $number;

但问题是我存储了加密的卡号。

他们最终看起来有很多不同,在我的表单类型中,我这样做是为了加密值并删除所有不必要的东西。

public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('number') ->add('expiration_year', 'choice', array( 'required' => true, 'choices' => $this->buildYearChoices() )) ->add('expiration_month', 'choice', array( 'required' => true, 'choices' => array( '01' => '01', '02' => '02', '03' => '03', '04' => '04', '05' => '05', '06' => '06', '07' => '07', '08' => '08', '09' => '09', '10' => '10', '11' => '11', '12' => '12', ) )) ->add('cvc', 'text'); $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) { $data = $event->getData(); $number = preg_replace("/[^0-9]/", "", $data['number']); $data['number'] = $number; $event->setData($data); }); $builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) { $credit_card = $event->getData(); $number = $credit_card->getNumber(); $customer_helper = $this->container->get('customer_helper'); $crypt = $customer_helper->encryptCreditCardNumber($number); $credit_card->setNumber($crypt); $event->setData($credit_card); }); }

即使我知道表单验证是在pre_submit上执行的,但是当我在SUBMIT上对它进行加密时,我仍然会收到验证错误

编辑:加密和解密emthods:

public function encryptCreditCardNumber($plaintext) { $ivSize = mcrypt_get_iv_size(self::CIPHER, self::MODE); //Gets the size of the IV belonging to a specific cipher/mode combination. $iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_RANDOM); //Creates an initialization vector (IV) from a random source. $ciphertext = mcrypt_encrypt(self::CIPHER, $this->container->getParameter('cc_encryption_key'), $plaintext, self::MODE, $iv); //Encrypts the data and returns it. return base64_encode($iv.$ciphertext); //Encode Base 64 } public function decryptCreditCardNumber($ciphertext) { $ciphertext = base64_decode($ciphertext); //Decode Base 64 $ivSize = mcrypt_get_iv_size(self::CIPHER, self::MODE); //Gets the size of the IV belonging to a specific cipher/mode combination. if (strlen($ciphertext) < $ivSize) { throw new Exception('Missing initialization vector'); } $iv = substr($ciphertext, 0, $ivSize); $ciphertext = substr($ciphertext, $ivSize); $plaintext = mcrypt_decrypt(self::CIPHER, $this->container->getParameter('cc_encryption_key'), $ciphertext, self::MODE, $iv); //Decrypts the data and returns it. return rtrim($plaintext, "\0"); }

i have a CreditCard entity, now i want to perform basic validation on this, in the entity, such as:

/** * @ORM\Column(name="number", type="string", length=255) * @Assert\CardScheme( * schemes={"VISA", "MASTERCARD", "DISCOVER", "DINERS"}, * message="The card number is not valid, we only support Visa, Mastercard, Discover og Diners club." * ) */ private $number;

But the issue is that i am storing the card numbers encrypted.

They end up looking a whole lot different, and in my form type, i do this to encrypt the values and remove all the uneccesary stuff.

public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('number') ->add('expiration_year', 'choice', array( 'required' => true, 'choices' => $this->buildYearChoices() )) ->add('expiration_month', 'choice', array( 'required' => true, 'choices' => array( '01' => '01', '02' => '02', '03' => '03', '04' => '04', '05' => '05', '06' => '06', '07' => '07', '08' => '08', '09' => '09', '10' => '10', '11' => '11', '12' => '12', ) )) ->add('cvc', 'text'); $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) { $data = $event->getData(); $number = preg_replace("/[^0-9]/", "", $data['number']); $data['number'] = $number; $event->setData($data); }); $builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) { $credit_card = $event->getData(); $number = $credit_card->getNumber(); $customer_helper = $this->container->get('customer_helper'); $crypt = $customer_helper->encryptCreditCardNumber($number); $credit_card->setNumber($crypt); $event->setData($credit_card); }); }

Even tho i know the form validation is performed pre_submit, i stil get a validation error, when i encrypt it on SUBMIT instead

EDIT: Encrypt and decrypt emthods:

public function encryptCreditCardNumber($plaintext) { $ivSize = mcrypt_get_iv_size(self::CIPHER, self::MODE); //Gets the size of the IV belonging to a specific cipher/mode combination. $iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_RANDOM); //Creates an initialization vector (IV) from a random source. $ciphertext = mcrypt_encrypt(self::CIPHER, $this->container->getParameter('cc_encryption_key'), $plaintext, self::MODE, $iv); //Encrypts the data and returns it. return base64_encode($iv.$ciphertext); //Encode Base 64 } public function decryptCreditCardNumber($ciphertext) { $ciphertext = base64_decode($ciphertext); //Decode Base 64 $ivSize = mcrypt_get_iv_size(self::CIPHER, self::MODE); //Gets the size of the IV belonging to a specific cipher/mode combination. if (strlen($ciphertext) < $ivSize) { throw new Exception('Missing initialization vector'); } $iv = substr($ciphertext, 0, $ivSize); $ciphertext = substr($ciphertext, $ivSize); $plaintext = mcrypt_decrypt(self::CIPHER, $this->container->getParameter('cc_encryption_key'), $ciphertext, self::MODE, $iv); //Decrypts the data and returns it. return rtrim($plaintext, "\0"); }

最满意答案

您可以捕获prePersist事件prePersist和preUpdate以便在运行时将普通代码替换为加密代码(在保存数据之前,在表单验证之后)。

要解密它,您可以使用postLoad 。

更多关于教义事件的信息在这里 。

请注意,学说事件与表单事件不同,不会干扰表单或验证(甚至可能根本没有表单)。

编辑:注入密钥

每当您需要将静态信息注入实体(例如参数或函数)时,请使用依赖注入。

如果你有一个bundle,请转到DependencyInjection文件夹并编辑Configuration.php文件(或者是另一个文件?我现在不记得了)。

您想要找到的是使用load方法加载参数的方法。

在此之后,从配置中获取所需的参数,并将其设置为类的静态成员,如下所示:

MyEntity::$secretKey = $configuration->getParameter('secretkey');

在实体内部,只需仔细阅读以下信息:

self::$secretKey

我把它从头顶上写下来,所以很多不准确的东西都可以插入。必要时纠正。 关键在于静态注入参数,如上所示。

You can catch the doctrine events prePersist and preUpdate to replace the plain code with the encrypted one on the fly (right before persisting the data, well after form validation).

To decrypt it, you can use postLoad.

More about doctrine events is here.

Note that the doctrine events are different from the form events and do not interfere with the form or validation (there might even not be a form at all).

EDIT: Inject key

Whenever you need to inject static information into an entity, such as a parameter or a function, use dependency injection.

If you have a bundle, go to the DependencyInjection folder and edit the Configuration.php file (or was it the other one? I don't remember now).

What you want to find is the method that loads the parameters with the load method.

Right after that, fetch the desired parameter from the configuration and set it in a static member of the class with something like this:

MyEntity::$secretKey = $configuration->getParameter('secretkey');

Inside the entity just peruse the information with:

self::$secretKey

I write this out of the top of my head, so many inaccuracies may have slipped in. Correct where necessary. The point is all about injecting the parameter statically as shown above.