Ebooks

Symfony form tutorial

Symfony form tutorial shows how to create and process a form in Symfony. In this tutorial we do not use a Symfony form builder.

Symfony

Symfony is a set of reusable PHP components and a PHP framework for web projects. Symfony was published as free software in 2005. The original author of Symfony is Fabien Potencier. Symfony was heavily inspired by the Spring Framework.

HTML form

HTML forms are used for interaction between a user and a web site or application. They allow users to send data to the web site. An HTML Form is made of one or more widgets. Those widgets can be text fields, select boxes, buttons, checkboxes, or radio buttons. Those widgets are often paired with a label that describes their purpose.

Symfony form example

In the following example, we create an HTML form. The data from the form is processed by a Symfony controller.

$ composer create-project symfony/skeleton myform

With composer, we create a new Symfony skeleton project.

$ cd myform

We go to the project directory.

$ composer require annotations
$ composer require maker
$ composer require twig

We install three modules: annotations, maker, and twig.

$ composer require server --dev

We install the development web server.

$ bin/console make:controller HomeController

We create a HomeController.

src/Controller/HomeController.php
namespace App\Controller;

use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class HomeController extends Controller
{
    /**
     * @Route("/", name="home")
     */
    public function index()
    {
        return $this->render('home/index.html.twig');
    }
}

The HomeController returns a home page that contains the HTML form.

templates/home/index.html.twig
{% extends 'base.html.twig' %}

{% block title %}Home page{% endblock %}

{% block body %}

<section class="ui container">

    <form class="ui form" action="message" method="post">
    
        <div class="field">
            <label>Name:</label>
            <input type="text" name="name">
        </div>

        <div class="field">
            <label>Message</label>
            <input type="text" name="message">
        </div>

        <button class="ui button" type="submit">Send</button>

    </form>

</section>

{% endblock %}

The HomeController returns a home page that contains the HTML form. The form contains two input fields. The content of these fields will be passed in a request object via two request attributes.

{% extends 'base.html.twig' %}

The template inherits from the base.html.twig file, which has base markup that will be shared. For instance, we include the files of the Semantic UI CSS framework.

templates/base.html.twig
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>{% block title %}Welcome!{% endblock %}</title>
        <link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.1/semantic.min.css" 
                 rel="stylesheet">
    </head>
    
    <body>
        {% block body %}{% endblock %}
    </body>


<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.1/components/semantic.min.js">    
</html>

The base.html.twig template contains code that is shared by other template files. It defines blocks that will be replaced in children templates.

$ bin/console make:controller MessageController

A MessageController is created.

src/Controller/MessageController.php
<?php

namespace App\Controller;

use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;

class MessageController extends Controller
{
    /**
     * @Route("/message", name="message", methods="POST")
     */
    public function index(Request $request)
    {
        $name = $request->get("name", "Guest");
        $message = $request->get("message", "Hello there!");
        
        return $this->render('message/index.html.twig', ["name"=>$name, 
            "message"=>$message]);
    }
}

The MessageController processes the form.

/**
 * @Route("/message", name="message", methods="POST")
 */

The @Route annotation maps the message path to the index() method. The methods parameter defines the request type.

public function index(Request $request)

We inject the Request object to the method.

$name = $request->get("name", "Guest");
$message = $request->get("message", "Hello there!");

From the request object, we get the two request parameters. The second parameter of the get() method is a default value if the parameter is not defined.

return $this->render('message/index.html.twig', ["name"=>$name, 
    "message"=>$message]);

We render the message/index.html.twig template. We pass the template the two variables.

templates/message/index.html.twig
{% extends 'base.html.twig' %}

{% block title %}Show message{% endblock %}

{% block body %}

{{name}} says: {{message}}

{% endblock %}

Finally, we have the template file that shows the message to the user. The variables are shown with the {{}} syntax.

In this tutorial we have created and processed a simple HTML form in a Symfony application.

You might also be interested in the following related tutorials: Introduction to Symfony, Symfony Request tutorial, Symfony DBAL tutorial, PHP tutorial.