Symfony. 5 trucos del componente Validator
Recopilación de algunas características del componente Validator de Symfony que puede que no conozcas
El componente Validator de Symfony es probablemente uno de esos grandes desconocidos aunque paradójicamente lo empleemos en la mayoría de proyectos donde sea necesario validar formularios y/o entidades. Más allá de permitirnos realizar las comprobaciones típicas como por ejemplo la longitud de un string o si una cadena representa un número de teléfono, el componente Validator cuenta con una serie de características que resultan realmente útiles a medida que profundizamos en ellas.
En este artículo me he animado a reunir algunas de las que más me han sorprendido a lo largo de estos años durante los que he trabajado con este componente para que no tengáis que sumergiros en su documentación hasta dar con ellas.
¡Vamos a verlas!
Validación automática
En Symfony 4.3 se introdujo una característica muy interesante: validar de forma automática nuestras entidades del ORM en base al mapeo que definamos para sus propiedades.
Por ejemplo, hasta ese momento si nosotros definíamos la entidad Person
:
/** @ORM\Entity */
class Person
{
// ...
/** @ORM\Column(type="string", length=5) */
public $zip;
}
Y tratábamos de validar la siguiente instancia:
$person = new Person();
$person->setZip('1111111111111111');
$violationList = $validator->validate($person);
Lo que obteníamos era una lista vacía de errores de validación pese a que posteriormente se generase un error al enviar la entidad a la base de datos (los valores de la columna zip
sólo pueden tener 5 caracteres).
Desde Symfony 4.3 podemos activar la validación automática a partir del mapeo añadiendo lo siguiente a la configuración del componente Validator en el archivo config/packages/validator.yaml
:
framework:
validation:
...
auto_mapping:
App\Entity\: []
NotCompromisedPassword
Una de las validaciones más llamativas que podemos incluir dentro de nuestras aplicaciones es la que nos permite comprobar que la contraseña introducida por el usuario para su cuenta no ha sido hackeada anteriormente empleando para ello el servicio https://haveibeenpwned.com/.
Para incluir esta validación bastará con añadirla al campo que representa la contraseña del usuario:
App\Entity\User:
properties:
rawPassword:
- NotCompromisedPassword
Como curiosidad deciros que la contraseña no es enviada al servicio haveibeenpwned, sino que tan sólo los primeros bytes del hash SHA-1 de la contraseña son enviados, de modo que se asegura que esta comprobación se realiza de forma anónima (no vaya a ser peor el remedio que la enfermedad 🤣🤣🤣)
Si queréis leer más sobre esta validación podéis hacerlo desde la propia documentación de Symfony: https://symfony.com/doc/current/reference/constraints/NotCompromisedPassword.html
Callback
Una de las constraints más versátiles que nos ofrece el componente Validator de Symfony es Callback
, ya que nos permite especificar el nombre de un método de la entidad que queremos ejecuta a fin de realizar la validación. esto puede resulta muy útil en el momento en que necesitemos realizar alguna comprobación más compleja.
Por ejemplo, yo la descubrí cuando tuve que realizar la comprobación de que el usuario había rellenado o bien el teléfono o bien el email, algo que no podía realizar con las constraints proporcionadas por el componente.
El uso de la constraint Callback
es muy sencillo. Lo primero que haremos será añadirla al conjunto de validaciones de nuestra entidad o clase:
App\Entity\Person:
constraints:
- Callback: validateContact
Y a continuación dentro de la clase implementar el método que hayamos escogido, en nuestro caso validateContact
:
class Person
{
public function validateContact(ExecutionContextInterface $context, $payload)
{
// check if the name is actually a fake name
if (empty($this->telephone) && empty($this->email)) {
$context->buildViolation('We need at least your email or your telephone')
->atPath('email')
->addViolation();
}
}
}
UniqueEntity
Otra constraint muy útil del componente Validator es UniqueEntity
la cual viene a solucionar de golpe el problema de comprobar si un email (o cualquier otro campo) ya se ha usado en nuestra aplicación.
Esta constraint la tendremos que añadir al nivel de la clase, es decir, no asociarla a ninguna propiedad sino a la clase donde queremos realizar la validación:

Además nos provee de una serie de opciones con el fin de personalizar el proceso de búsqueda de la entidad en la base de datos:
em
nos permite especificar elentity manager
que emplearemos para buscar la entidad.entityClass
, nos permite especificar sobre qué clase queremos realizar la comprobación ya que no tiene por qué ser sobre la que estamos aplicando la validación.
Pese a la potencia de esta constraint tiene una limitación: de momento no podemos usarla en DTO’s tal y como podéis leer aquí: https://github.com/symfony/symfony/issues/22592
Por lo que parece habrá que esperar un tiempo para poder emplearla de este modo.
Choice + Callback
Este ha sido uno de mis descubrimientos más recientes y nos permite validar un campo que sólo puede recibir una serie concreta de valores. Por ejemplo, imaginad que tenéis un campo locale
que sólo tiene como valores válidos es
y en
, ambos definidos como un enumerado dentro de una clase:

Validar el campo locale
a partir de los valores definidos en esta clase es tan sencillo como añadir lo siguiente:

Como veis, la constraint Choice
nos permite especificar un callback
que recibe dos argumentos: la clase y su método estático que queremos ejecutar para obtener las opciones válidas. Muy muy útil.
Bola extra. User Password
Si en vuestra aplicación permitís a vuestro usuario cambiar su contraseña probablemente querráis validar que introduce la antigua para evitar fallos de seguridad. Esta tarea es muy sencilla de realizar gracias a la constraint UserPassword
, la cual lleva a cabo esa validación sin necesidad de que nosotros escribamos ningún tipo de lógica.

Conclusiones
Como habéis podido ver, el componente Validator de Symfony tiene muchas más opciones que la mera comprobación básica de valores del dia a día. Además, conforme Symfony evoluciona se van añadiendo nuevas características a este componente, y cada vez son más los valores que tienen su propia validación (por ejemplo, actualmente ya podemos comprobar tarjetas de crédito, números IBAN, etc.).
Por eso mi consejo es que de vez en cuando echéis un ojo a la fantástica documentación de Symfony con el objetivo de estar al tanto de las últimas novedades que van saliendo, ya que muchas de ellas nos simplificarán las tareas enormemente.
¿Quieres recibir más artículos como este?
Si te ha gustado este artículo te animo a que te suscribas a la newsletter que envío cada domingo con publicaciones similares a esta y más contenido recomendado: 👇👇👇