Recherche…
Remarques
En fait, la validation de formulaire est basée sur un composant nommé " Validator Component ".
Vous pouvez souvent utiliser le service dédié si vous n'avez pas à afficher un formulaire dans un modèle. Comme les API. Vous pouvez valider les données de la même manière, comme ceci:
Par exemple, basé sur le doc de symfony :
$validator = $this->get('validator');
$errors = $validator->validate($author);
if (count($errors) > 0) {
/*
* Uses a __toString method on the $errors variable which is a
* ConstraintViolationList object. This gives us a nice string
* for debugging.
*/
$errorsString = (string) $errors;
}
Validation Symfony à l'aide d'annotations
- Activer la validation à l'aide d'annotations dans le fichier
app/config/config.yml
framework:
validation: { enable_annotations: true }
- Créez un
AppBundle/Entity
entité dansAppBundle/Entity
. Les validations sont effectuées avec les annotations@Assert
.
<?php
# AppBundle/Entity/Car.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Car
*
* @ORM\Table(name="cars")
* @ORM\Entity(repositoryClass="AppBundle\Repository\CarRepository")
*/
class Car
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=50)
* @Assert\NotBlank(message="Please provide a name")
* @Assert\Length(
* min=3,
* max=50,
* minMessage="The name must be at least 3 characters long",
* maxMessage="The name cannot be longer than 50 characters"
* )
* @Assert\Regex(
* pattern="/^[A-Za-z]+$/",
* message="Only letters allowed"
* )
*/
private $name;
/**
* @var string
*
* @ORM\Column(name="number", type="integer")
* @Assert\NotBlank(message="Please provide a number")
* @Assert\Length(
* min=1,
* max=3,
* minMessage="The number field must contain at least one number",
* maxMessage="The number field must contain maximum 3 numbers"
* )
* @Assert\Regex(
* pattern="/^[0-9]+$/",
* message="Only numbers allowed"
* )
*/
private $number;
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return Car
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set number
*
* @param integer $number
*
* @return Car
*/
public function setNumber($number)
{
$this->number = $number;
return $this;
}
/**
* Get number
*
* @return integer
*/
public function getNumber()
{
return $this->number;
}
}
- Créez un nouveau formulaire dans le
AppBundle/Form
.
<?php
# AppBundle/Form/CarType.php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
class CarType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', TextType::class, ['label'=>'Name'])
->add('number', IntegerType::class, ['label'=>'Number'])
;
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Car'
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
// TODO: Implement setDefaultOptions() method.
}
public function getName()
{
return 'car_form';
}
}
- Créez une nouvelle route et une nouvelle méthode d'action dans
AppBundle/Controller/DefaultController.php
. La route sera également déclarée avec des annotations, alors assurez-vous d'avoir importé cette route dans le fichier de route principal (app/config/routing.yml
).
<?php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use AppBundle\Entity\Car;
use AppBundle\Form\CarType;
class DefaultController extends Controller
{
/**
* @Route("/car", name="app_car")
*/
public function carAction(Request $request)
{
$car = new Car();
$form = $this->createForm(
CarType::class,
$car,
[
'action' => $this->generateUrl('app_car'),
'method'=>'POST',
'attr'=>[
'id'=>'form_car',
'class'=>'car_form'
]
]
);
$form->handleRequest($request);
return $this->render(
'AppBundle:Default:car.html.twig',[
'form'=>$form->createView()
]
);
}
}
- Créez la vue dans
AppBundle/Resources/views/Default/car.html.twig
.
{% extends '::base.html.twig' %}
{% block body %}
{{ form_start(form, {'attr': {'novalidate':'novalidate'}}) }}
{{ form_row(form.name) }}
{{ form_row(form.number) }}
<button type="submit">Go</button>
{{ form_end(form) }}
{% endblock %}
- Lancez le serveur intégré de Symfony (
php bin/console server:run
) et accédez à la route127.0.0.1:8000/car
dans votre navigateur. Il devrait y avoir un formulaire composé de deux zones de saisie et d’un bouton d’envoi. Si vous appuyez sur le bouton d'envoi sans saisir de données dans les zones de saisie, les messages d'erreur s'afficheront.
Validation Symfony avec YAML
- Créez un
AppBundle/Entity
entité dansAppBundle/Entity
. Vous pouvez le faire manuellement ou en utilisant la commandephp bin/console doctrine:generate:entity
Symfonyphp bin/console doctrine:generate:entity
et en renseignant les informations requises à chaque étape. Vous devez spécifier l'optionyml
au niveau duConfiguration format (yml, xml, php or annotation)
.
<?php
# AppBundle/Entity/Person.php
namespace AppBundle\Entity;
/**
* Person
*/
class Person
{
/**
* @var int
*/
private $id;
/**
* @var string
*/
private $name;
/**
* @var int
*/
private $age;
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return Person
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set age
*
* @param integer $age
*
* @return Person
*/
public function setAge($age)
{
$this->age = $age;
return $this;
}
/**
* Get age
*
* @return int
*/
public function getAge()
{
return $this->age;
}
}
- Créez les informations de mappage d'entité pour la classe d'entité. Si vous utilisez la commande
php bin/console doctrine:generate:entity
Symfonyphp bin/console doctrine:generate:entity
, le code suivant sera généré automatiquement. Sinon, si vous n'utilisez pas la commande, vous pouvez créer le code suivant à la main.
# AppBundle/Resources/config/doctrine/Person.orm.yml
AppBundle\Entity\Person:
type: entity
table: persons
repositoryClass: AppBundle\Repository\PersonRepository
id:
id:
type: integer
id: true
generator:
strategy: AUTO
fields:
name:
type: string
length: '50'
age:
type: integer
lifecycleCallbacks: { }
- Créez la validation pour la classe Entity.
# AppBundle/Resources/config/validation/person.yml
AppBundle\Entity\Person:
properties:
name:
- NotBlank:
message: "Name is required"
- Length:
min: 3
max: 50
minMessage: "Please use at least 3 chars"
maxMessage: "Please use max 50 chars"
- Regex:
pattern: "/^[A-Za-z]+$/"
message: "Please use only letters"
age:
- NotBlank:
message: "Age is required"
- Length:
min: 1
max: 3
minMessage: "The age must have at least 1 number in length"
maxMessage: "The age must have max 3 numbers in length"
- Regex:
pattern: "/^[0-9]+$/"
message: "Please use only numbers"
- Créez un nouveau formulaire dans le
AppBundle/Form
.
<?php
# AppBundle/Form/PersonType.php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
class PersonType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', TextType::class, ['label'=>'Name'])
->add('age', IntegerType::class, ['label'=>'Age'])
;
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Person'
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
// TODO: Implement setDefaultOptions() method.
}
public function getName()
{
return 'person_form';
}
}
- Créez une nouvelle route dans
AppBundle/Resources/config/routing.yml
app_person:
path: /person
defaults: { _controller: AppBundle:Default:person }
- Créez maintenant une nouvelle méthode d'action pour cette route.
<?php
# AppBundle/Controller/DefaultController.php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use AppBundle\Entity\Person;
use AppBundle\Form\PersonType;
class DefaultController extends Controller
{
public function personAction(Request $request)
{
$person = new Person();
$form = $this->createForm(
PersonType::class,
$person,
[
'action' => $this->generateUrl('app_person'),
'method'=>'POST',
'attr'=>[
'id'=>'form_person',
'class'=>'person_form'
]
]
);
$form->handleRequest($request);
return $this->render(
'AppBundle:Default:person.html.twig', [
'form'=>$form->createView()
]
);
}
}
- Créez la vue dans
AppBundle/Resources/views/Default/person.html.twig
{% extends '::base.html.twig' %}
{% block body %}
{{ form_start(form, {'attr': {'novalidate':'novalidate'}}) }}
{{ form_row(form.name) }}
{{ form_row(form.age) }}
<button type="submit">Go</button>
{{ form_end(form) }}
{% endblock %}
- Lancez le serveur intégré de Symfony (
php bin/console server:run
) et accédez à la route127.0.0.1:8000/person
dans votre navigateur. Il devrait y avoir un formulaire composé de deux zones de saisie et d’un bouton d’envoi. Si vous appuyez sur le bouton d'envoi sans saisir de données dans les zones de saisie, les messages d'erreur s'afficheront.
Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow