Ricerca…


Osservazioni

In effetti, la convalida del modulo si basa su un componente, denominato " Componente Validatore ".

È spesso possibile utilizzare il servizio dedicato se non è necessario mostrare un modulo in un modello. Mi piacciono le API. Puoi convalidare i dati nello stesso modo, come questo:

Ad esempio, basato su symfony doc :

$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;
}

Convalida di symfony usando le annotazioni

  • Abilita la convalida usando le annotazioni nel file app/config/config.yml
framework:
    validation: { enable_annotations: true }
  • Creare un'entità nella AppBundle/Entity . Le convalide vengono eseguite con annotazioni @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;
    }
}
  • Crea un nuovo modulo nella 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';
    }
}
  • Crea un nuovo percorso e un nuovo metodo di azione in AppBundle/Controller/DefaultController.php . Anche il percorso verrà dichiarato con annotazioni, quindi assicurati di aver importato questa rotta nel file di percorso principale ( 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()
            ]
        );
    }
}
  • Creare la vista in 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 %}
  • Avvia il server integrato di Symfony ( php bin/console server:run ) e accedi al percorso 127.0.0.1:8000/car nel tuo browser. Ci dovrebbe essere una forma composta da due caselle di input e un pulsante di invio. Se si preme il pulsante di invio senza immettere alcun dato nelle caselle di immissione, verranno visualizzati i messaggi di errore.

Convalida di symfony usando YAML

  • Creare un'entità nella AppBundle/Entity . Puoi farlo manualmente o usando il comando di Symfony php bin/console doctrine:generate:entity e riempiendo le informazioni richieste in ogni passaggio. È necessario specificare l'opzione yml al passaggio del Configuration 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;
    }
}
  • Creare le informazioni di mapping Entità per la classe Entity. Se stai usando il comando di Symfony php bin/console doctrine:generate:entity , il seguente codice verrà generato automaticamente. Altrimenti, se non si utilizza il comando, è possibile creare manualmente il seguente codice.
# 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: {  }
  • Creare la convalida per 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"
  • Crea un nuovo modulo nella 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';
    }
}
  • Crea un nuovo percorso in AppBundle/Resources/config/routing.yml
app_person:
    path: /person
    defaults: { _controller: AppBundle:Default:person }
  • Ora crea un nuovo metodo di azione per quella rotta.
<?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()
            ]
        );
    }
}
  • Creare la vista in 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 %}
  • Avvia il server integrato di Symfony ( php bin/console server:run ) e accedi al percorso 127.0.0.1:8000/person nel tuo browser. Ci dovrebbe essere una forma composta da due caselle di input e un pulsante di invio. Se si preme il pulsante di invio senza immettere alcun dato nelle caselle di immissione, verranno visualizzati i messaggi di errore.


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow