Symfony2的做表单验证而不是数据库验证
问题描述:
我有一个信用卡式的实体,现在我想在此执行基本验证,在实体,如:Symfony2的做表单验证而不是数据库验证
/**
* @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,我还是老样子得到验证错误,当我对它进行加密上提交,而不是
编辑:加密和解密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
和preUpdate
,以在运行中(在保留数据之前,很好地在表单验证之后)用加密的代码替换普通代码。
要解密它,你可以使用postLoad
。
请注意,原则事件不同于表单事件,不会干扰表单或验证(甚至可能根本没有表单)。
编辑:进样关键
每当你需要注入静态信息到一个实体,比如一个参数或功能,使用依赖注入。
如果您有捆绑软件,请转到DependencyInjection
文件夹并编辑Configuration.php
文件(或者是另一个?我现在不记得了)。
您想要查找的是使用load
方法加载参数的方法。
权后,从配置获取需要的参数,这样的设置在类的静态成员:
MyEntity::$secretKey = $configuration->getParameter('secretkey');
实体里面只是细读与信息:
self::$secretKey
我把这个写在了我的头顶,这么多的不准确之处可能已经溜进去了。关键是全部关于静态注入参数如上所示。
答
您可以创建验证目的的非映射实体属性:
/**
* @Assert\CardScheme(
* schemes={"VISA", "MASTERCARD", "DISCOVER", "DINERS"},
* message="The card number is not valid, we only support Visa, Mastercard, Discover og Diners club."
*)
*/
private $rawNumber;
/**
* @ORM\Column(name="number", type="string", length=255)
*/
private $number;
,然后设置数量与表单验证后rawNumber的加密值:
$creditCard->setNumber(
your_encryption_function(
$creditCard->getRawNumber()
)
);
问题与此,是否需要将事件置于我的实体中?加密密钥存储在parameters.yml中,所以我不保存在代码中,但我无法将容器放入实体 –
而这样做会是不好的做法,据我了解 –
我发布了我的加密和解密方法,以澄清 –