Symfony Forms maakt het eenvoudig om formulieren te bouwen, in te dienen en te valideren. Je definieert een Form Type-klasse met de velden, koppelt die aan een controller, en toont het formulier in Twig. Validatieregels voeg je toe als Constraints.
1 Hoe werkt een Symfony formulier?
Een Symfony formulier bestaat uit drie onderdelen die samenwerken:
Form Type klasse src/Form/ProductType.php
Beschrijft welke velden het formulier heeft, welk type ze zijn (tekst, getal, datum…) en welke validatieregels gelden.
Controller src/Controller/...
Maakt het formulier aan, verwerkt de ingediende data en slaat deze op in de database.
Twig template templates/...
Toont het formulier als HTML. Symfony genereert de labels, invoervelden en foutmeldingen automatisch.
2 Een Form Type klasse aanmaken
De console genereert een Form Type op basis van een bestaande Entity:
# Maak een form type aan voor de Product entity
php bin/console make:form ProductType Product
Dit genereert de volgende klasse, die je daarna aanpast:
<?php
namespace App\Form;
use App\Entity\Product;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints as Assert;
class ProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
// Tekstveld voor de naam
->add('naam', TextType::class, [
'label' => 'Productnaam',
'attr' => ['placeholder' => 'bijv. Laptop Pro'],
'constraints' => [
new Assert\NotBlank(message: 'Vul een naam in.'),
new Assert\Length(min: 2, max: 100),
],
])
// Geldbedrag voor de prijs
->add('prijs', MoneyType::class, [
'label' => 'Prijs',
'currency' => 'EUR',
'constraints' => [
new Assert\NotBlank(message: 'Vul een prijs in.'),
new Assert\Positive(message: 'Prijs moet positief zijn.'),
],
])
;
}
public function configureOptions(OptionsResolver $resolver): void
{
// Koppel dit formulier aan de Product entity
$resolver->setDefaults(['data_class' => Product::class]);
}
}
3 Het formulier in de controller
In de controller maak je het formulier aan, verwerk je de POST-data en sla je het object op. Eén methode behandelt zowel GET (toon formulier) als POST (verwerk data).
use App\Form\ProductType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
#[Route('/producten/nieuw', name: 'product_nieuw')]
public function nieuw(Request $request, EntityManagerInterface $em): Response
{
// Maak een leeg Product-object aan
$product = new Product();
// Maak het formulier aan en koppel het aan het object
$form = $this->createForm(ProductType::class, $product);
// Verwerk de ingediende data (alleen bij POST)
$form->handleRequest($request);
// Controleer: is het formulier ingediend én valide?
if ($form->isSubmitted() && $form->isValid()) {
// $product heeft nu automatisch de ingevulde waarden
$em->persist($product);
$em->flush();
$this->addFlash('success', 'Product toegevoegd!');
return $this->redirectToRoute('product_index');
}
// Geef het formulier-object door aan de template
return $this->render('product/nieuw.html.twig', [
'form' => $form,
]);
}
4 Het formulier tonen in Twig
Symfony geeft je handige Twig-functies om het formulier te renderen. Je kunt elk veld apart tonen of alles tegelijk met één regel.
{{ form_start(form) }}
{{ form_widget(form) }}
<button type="submit" class="btn btn-primary">Opslaan</button>
{{ form_end(form) }}
{{ form_start(form) }}
{# form_row toont: label + invoerveld + foutmelding #}
{{ form_row(form.naam) }}
{{ form_row(form.prijs) }}
{# Of nog meer controle: apart renderen #}
<div class="form-groep">
{{ form_label(form.naam) }}
{{ form_widget(form.naam, {'attr': {'class': 'mijn-input'}}) }}
{{ form_errors(form.naam) }}
</div>
<button type="submit">Product toevoegen</button>
{{ form_end(form) }}
🖥️ Zo ziet het gegenereerde formulier eruit
5 Validatie: constraints instellen
Symfony valideert automatisch op basis van Constraints die je aan de velden koppelt. Als validatie mislukt, worden foutmeldingen getoond — je hoeft zelf geen if-statements te schrijven.
use Symfony\Component\Validator\Constraints as Assert;
// Mag niet leeg zijn
new Assert\NotBlank(message: 'Dit veld is verplicht.')
// Lengte beperken
new Assert\Length(min: 2, max: 255, minMessage: 'Minimaal 2 tekens.')
// Getal moet positief zijn
new Assert\Positive(message: 'Moet een positief getal zijn.')
// Geldig e-mailadres
new Assert\Email(message: 'Vul een geldig e-mailadres in.')
// Minimale leeftijd
new Assert\GreaterThanOrEqual(18, message: 'Moet 18+ zijn.')
// Reguliere expressie
new Assert\Regex(pattern: '/^\d{4}[A-Z]{2}$/', message: 'Ongeldige postcode.')
6 Oefenen: bouw een smartphone formulier
Schrijf een SmartphoneType met drie velden: merk (tekst), model (tekst) en prijs (geld). Voeg validatie toe zodat alle velden verplicht zijn.
📋 Samenvatting
- ✓ Een Form Type klasse beschrijft de velden en validatieregels
- ✓
createForm(ProductType::class, $product)maakt het formulier aan in de controller - ✓
$form->handleRequest($request)verwerkt ingediende data - ✓
isSubmitted() && isValid()controleert of alles klopt - ✓ In Twig toon je het formulier met
form_start(form),form_row(form.veld)enform_end(form) - ✓ Constraints regelen validatie:
NotBlank,Length,Positive,Email, …
Gefeliciteerd!
Je hebt alle 6 lessen van SymfonyLearn doorlopen. Je kent nu de basisconcepten van Symfony: installatie, routes, controllers, Twig, Doctrine en formulieren.
Klaar voor de volgende stap? Gebruik je kennis in een echt Symfony-project!
Kennischeck
Test of je de stof begrepen hebt
Laatste les! Markeer hem als voltooid en voltooi de cursus.