我将Silex与Form和Validator提供程序一起使用。
我有一个非常简单的注册表格:
- 用户名
- 密码
- 密码确认
用户名必须是唯一的,如何检查?
这是我的代码:
$form = $app['form.factory']->createBuilder('form')
->add('username', 'text', array(
'constraints' => array(
new Assert'NotBlank(),
new Assert'Length(array('min' => 6, 'max' => 20)))
))
->add('password', 'repeated', array(
'constraints' => array(
new Assert'NotBlank(),
new Assert'Length(array('min' => 6, 'max' => 20))
)
))
->getForm();
对于Symfony,我知道存在UniqueEntity约束,但它附带了Doctrine,我只使用Doctrine DBAL(Silex提供商)
我想我可以使用Callback约束,但我想知道是否有比用SQL查询编写回调更好的解决方案。。。或者编写我自己的约束对象
感谢
好的,我决定创建自己的Constraint,因为我可以在电子邮件中重用它。所以,这就是我的实现:
UniqueEntry.php:
<?php
/**
* Ensure a value is unique in the database
*
* @author Thomas KELLER
*/
use Symfony'Component'Validator'Constraint;
use Symfony'Component'Validator'Exception'MissingOptionsException;
use Symfony'Component'Validator'Exception'InvalidArgumentException;
/**
* @Annotation
*/
class UniqueEntry extends Constraint {
public $notUniqueMessage = 'This value already exist in the database';
public $dbal_connection;
public $table;
public $field;
public function __construct($options = null)
{
parent::__construct($options);
if ($this->dbal_connection === null)
throw new MissingOptionsException(sprintf('The option "dbal_connection" is mandatory for constraint %s', __CLASS__), array('dbal_connection'));
if (!$this->dbal_connection instanceof 'Doctrine'DBAL'Connection)
throw new InvalidArgumentException(sprintf('The option "dbal_connection" must be an instance of Doctrine'DBAL'Connection for constraint %s', __CLASS__));
if ($this->table === null)
throw new MissingOptionsException(sprintf('The option "table" is mandatory for constraint %s', __CLASS__), array('table'));
if (!is_string($this->table) OR $this->table == '')
throw new InvalidArgumentException(sprintf('The option "table" must be a valid string for constraint %s', __CLASS__));
if ($this->field === null)
throw new MissingOptionsException(sprintf('The option "field" is mandatory for constraint %s', __CLASS__), array('field'));
if (!is_string($this->field) OR $this->field == '')
throw new InvalidArgumentException(sprintf('The option "field" must be a valid string for constraint %s', __CLASS__));
}
}
UniqueEntryValidator.php:
<?php
use Symfony'Component'Validator'Constraint;
use Symfony'Component'Validator'ConstraintValidator;
class UniqueEntryValidator extends ConstraintValidator
{
public function validate($value, Constraint $constraint)
{
$query = sprintf('SELECT `%s` FROM `%s` WHERE `%s` = ?',
$constraint->field,
$constraint->table,
$constraint->field);
$stmt = $constraint->dbal_connection->executeQuery($query, array($value));
if ($stmt->fetch())
$this->context->addViolation($constraint->notUniqueMessage);
}
}
我发布我的实施有建议,所以请随意评论;)