Tutoriel Vidéo Symfony Les nouveautés Symfony 4

Télécharger la vidéo

Il y a quelques jours de cela l'équipe de symfony a publiée la version 4 du framework. Même si la logique générale du framework reste la même, la structure a pas mal changée.

Sommaire

  • 00:00 Découverte et installation
  • 06:00 Symfony Flex
  • 08:40 Twig / Autowiring
  • 10:20 Workflow classique
  • 14:20 Migrations
  • 24:28 Symfony Encore

Installation

Avec cette nouvelle version il n'y a plus de commandes compliquées à mettre en place. L'installation du framework se fait maintenant via composer par défaut.

composer create-project symfony/skeleton mon-application

Une fois l'installation faite on peut tout de suite lancer le serveur de développement à l'aide du serveur interne de PHP.

php -S 127.0.0.1:8000 -t public

En vous rendant sur http://localhost:80000 vous devriez voir la page d'accueil de Symfony.

Une base de micro framework

Dès l'installation on peut déjà remarquer le faible nombre de dépendances. Plutôt que de charger une tonne de dépendance par défaut, le framework arrive avec le strict minimum et il faudra charger les composants que l'on souhaitera utiliser.
L'architecture des dossiers a aussi changé :

  • bin, contient l'éxécutable console nécessaire pour éxécuter la commande php bin/console`.
  • config, contient les yaml pour configurer le framework. Les configurations spécifiques aux modules sont rangées dans un sous dossier packages.
  • public, est le dossier qui servira de racine pour notre serveur web.
  • src, accueillera les sources PHP de notre application. Par défaut, ce dossier correspond au namespace \App\`.
  • var, contiendra les fichiers temporaires et les logs.

On remarquera surtout la disparition du dossier AppBundle au profit d'un simple dossier src. Le framework a donc moins d'opinions sur la structure à adopter pour votre projet et vous pouvez choisir de séparer votre logiques en utilisant les namespaces si besoin.

Symfony Flex

L'installation de composants supplémentaires se fait simplement gràce au plugin composer flex chargé par défaut. Par exemple, pour supporter twig et les annotations :

composer require twig annotations

Le plugin va chercher une recette (disponible dans le dépôt recipes ou recipes-contrib), télécharger les dépendances nécessaires et copier les fichiers de configuration dans le projet. Il n'y a donc aucune étapes supplémentaires (plus de lignes à rajouter manuellement dans le AppKernel.php, de configuration à copier coller dans des yaml).

Migrations par défaut

Le concept de migrations pour la base de données n'est pas nouveau mais était avant séparé dans un bundle dédié (non installé par défaut). Avec les recettes flex le système de migration est importé en même temps que l'ORM doctrine :

composer require orm maker

Après avoir modifié la configuration pour la base de données on peut créer la base de données

php bin/console doctrine:database:create

Puis créer une entitée

php bin/console make:entity Post

On édite ensuite cette entitée pour ajouter les champs que l'on souhaite utiliser.

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\PostRepository")
 */
class Post
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string"))
     */
    private $title;

    /**
     * @ORM\Column(type="text"))
     */
    private $content;

    /**
     * @ORM\Column(type="boolean"))
     */
    private $published;
}

Il est ensuite possible de générer la migration à l'aide de la commande

php bin/console doctrine:migrations:diff

Ce qui aura pour effet de générer un fichier /src/Migrations/Version20171205153113.php qui contiendra les requêtes SQL à éxécuter pour faire évoluer votre base de données. Vous pourrez ensuite éxécuter cette migration à l'aide de la commande.

php bin/console doctrine:migrations:migrate

Il est toujours possible d'utiliser la commande doctrine:schema:update mais cette dernière n'est plus mis en avant dans la documentation.

Au revoir Assetic, bonjour Encore

Avec cette nouvelle release un nouveau module va vous permettre de gérer vos assets CSS et JavaScript. Symfony Encore est un module NodeJS qui permet de gérer la conversions des assets (en proposant une API simplifiée pour intéragir avec webpack). L'installation peut se faire via npm, ou vous pouvez charger la configuration via la recette encore.

composer require encore asset

Cette recette va copier la configuration webpack.config.js et le fichier package.json. Vous devrez modifier la configuration webpack pour l'adapter à vos besoins.

On pourra ensuite utiliser les racourcis npm :

# Lance le serveur pour distribuer les assets
npm run dev-server
# Génère les assets en mode dev
npm run dev
# Génère les assets en mode dev, et à chaque changement
npm run watch
# Génère les assets en mode production
npm run build

Enfin, au niveau des templates on pourra utiliser la méthode asset() pour générer les liens vers nos assets.

asset('build/js/app.js')

Cette méthode va être capable de lire le fichier manifest.json généré par webpack afin de résoudre le chemin final vers les fichiers CSS/JS.

Autowiring

Cette modification est apparue dans la version 3.3 du framework mais je pense qu'il est important de la mentionner à nouveau. L'autowiring est activé par défaut dans le services.yaml et il n'est donc plus nécessaire de spécifier les services à injecter dans nos classes. Il est possible d'utiliser la commandes php bin/console debug:autoriwing apparue dans Symfony 3.4 pour connaitre l'ensemble des classes injectables.

Dans le cas des controllers il est aussi possible d'injecter les dépendances au niveau des actions :

class PostsController
{
    /**
     * @Route("/posts", name="posts")
     */
    public function index(Request $request, Environment $twig, RegistryInterface $doctrine, FormFactoryInterface $formFactory)
    {
        $posts = $doctrine->getRepository(Post::class)->findAll();
        $form = $formFactory->createBuilder(PostType::class, $posts[0])->getForm();

        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $doctrine->getEntityManager()->flush();
        }

        return new Response($twig->render('posts/index.html.twig', [
            'posts' => $posts,
            'form' => $form->createView()
        ]));
    }
}