Académique Documents
Professionnel Documents
Culture Documents
Installation
Dans les 2 cas l'installation peut se faire au travers de la commande create-
project de composer.
# Laravel
composer create-project laravel/laravel example-app
# Symfony
composer create-project symfony/skeleton:"6.3.*" my_project_directory
cd my_project_directory
composer require webapp
On notera aussi que les 2 frameworks intègre une commande (laravel pour Laravel
et symfony pour Symfony) que l'on peut utiliser pour piloter le framework et faire
certaines tâches (initialiser un projet par exemple).
Structure
La structure des 2 frameworks est similaire avec la présence d'un dossier public qui
servira de racine au serveur HTTP. Les sources sont placé dans un dossier src pour
Symfony et app dans le cas de Laravel. Dans les 2 cas la configuration se situera
dans le dossier config avec comme principale différence le format utilisé.
Laravel utilise des fichiers des PHP qui retourne des tableaux
Symfony utilise par défaut des fichier yaml
Les routes
Maintenant que les framework sont installés on va pouvoir créer notre première
route pour créer une page. Dans le cas de Laravel on commence par créer le
controller
<?php
namespace App\Http\Controllers;
// routes/web.php
Route::get('/hello', [HelloController::class, 'hello'])->name('hello');
Côté Symfony il est possible de déclarer les routes au travers d'attribut dans le
controller directement.
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
Gérer la requête
Pour les 2 frameworks il est possible d'injecter un paramètre dans nos controllers
pour récupérer la requête.
On notera que l'objet Request présent dans Laravel étend de la class Request de
Symfony pour proposer des méthodes plus rapides pour effectuer des opérations de
bases.
# Laravel
Route::get('/hello/{name}', [HelloController::class, 'hello']);
# Symfony
#[Route('/hello/{name}')]
Moteur de template
Pour rendre des pages HTML il sera possible d'utiliser un moteur de template et
c'est sur ce point qu'apparait une première différence entre les 2 frameworks.
Symfony utilise le moteur de template twig qui utilise sa propre syntaxe inspirée par
Django. Il est possible d'étendre le moteur en ajoutant des fonctions, filtres, et
balises
{% extends "base.html.twig" %}
{% block sidebar %}
{{ parent() }}
<p>This is appended to the master sidebar.</p>
{% endblock %}
{% block content %}
{% for post in posts %}
<article>
<h2>{{ post.title }}</h2>
<p>{{ post.excerpt }}</p>
<p><a href="{{ path('post.show', {slug: post.slug}) }}">Lire la suite</a></p>
</article>
{% endblock %}
@extends('layouts.app')
@section('sidebar')
@parent
@section('content')
@foreach($posts as $post)
<article>
<h2>{{ $post->title }}</h2>
<p>{{ $post->excerpt }}</p>
<p><a href="{{ route('post.show', ['slug' => $post->slug]) }}">Lire la suite</a></p>
</article>
@endforeach
@endsection
<form method="post">
<x-input :value="$post->title" label="Titre">
</form>
Formulaire
Une des tâche récurrente lorsque l'on fait du backend est la création et le traitement
de formulaire.
Symfony
Sur Symfony la création de formulaire passe par une classe dédiée qui va permettre
de représenter les données de notre formulaire. On notera la possibilité d'ajouter des
règle de validation sur les propriétés à l'aide d'attributs PHP.
<?php
namespace App\DTO;
class ContactDTO
{
#[Assert\NotBlank()]
#[Assert\Length(min: 3)]
public string $name = '';
#[Assert\NotBlank()]
#[Assert\Email()]
public string $email = '';
#[Assert\NotBlank()]
#[Assert\Length(min: 10)]
public string $message = '';
Ensuite on peut créer la classe qui va représenter notre formulaire et ces champs.
<?php
namespace App\Form;
use App\DTO\ContactDTO;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
return $this->render('contact.html.twig', [
'form' => $form,
]);
}
Côté template le formulaire peut être généré à l'aide de la fonction form qui est
injecté dans Twig par Symfony.
{{ form(form) }}
Laravel
Sur Laravel il n'existe pas de classe pour représenter le formulaire, ni pour générer
le formulaire. Dans notre template blade on créera donc notre formulaire de manière
classique (on pourra utiliser des includes ou des composants pour simplifier l'écirute
des champs).
<form method="post">
@csrf
<div>
<label for="name">Name :</label>
<input type="text" name="name" id="name" value="{{ old('name') }}">
@error('name')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
</div>
<div>
<label for="email">Email :</label>
<input type="email" id="email" name="email" id="email" value="{{ old('email') }}">
@error('email')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
</div>
<div>
<label for="message">Name :</label>
<textarea type="text" id="message" value="">{{ old('message') }}</textarea>
@error('message')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
</div>
<button type="submit">Nous contacter</button>
</form>
Lorsque le formulaire est soumis, et que des erreurs sont présentes, Laravel
redirigera automatiquement l'utilisateur vers le page précédente en sauvegardant les
données et les erreurs en session.
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
Ensuite, on va créer une route pour la méthode POST et on utilisera notre objet
requête en paramètre de la méthode.
API
Un autre cas d'utilisation de ces frameworks est la création d'une API.
Parser la requête
Lorsque l'on reçoit un appel il faut être capable de comprendre le contenu de la
requête et cela se fait très facilement pour les 2 frameworks. Côté Laravel on utilise
le même système de FromRequest.
<?php
use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
Réponse d'API
Pour répondre correctement à une demande il est nécessaire de sérialiser les
données pour transformer un objet en réponse valide (JSON par exemple). Laravel
dispose d'un type de classe, dédié à la transformation des objets.
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
Cette resource peut ensuite être utilisée pour renvoyer les données au niveau du
controller.
Le paramètre "groups" permet de contrôler les propriétés que l'on souhaite exposer
au travers d'attributs.
L'ORM
L'ORM est aussi un gros point de différence entre les 2 frameworks.
Laravel utilise par défaut Eloquent qui est un ORM basé sur Active Record où le
Model est à la fois responsable de représenter une entité, mais aussi de gérer la
persistence des informations.
// Récupération
$post = Post::find(1);
// Modification
$post->name = "Marc";
$post->save();
// Création
$post2 = Post::create(['name' => 'Jean']);
// Suppression
$post3->destroy();
Symfony utilise par défaut Doctrine qui est un ORM basé sur le principe du Data
Mapper où on sépare la notion d'entité (objet représentant les données), de
Repository (objet servant à récupérer des entités) et de Manager (objet responsable
de la persistance)
Eloquent a une syntaxe plus courte et une logique qui semble plus naturelle mais
cette apparente simplicité peut rapidement mener à des "fat models" car toute la
logique va être stocké au même endroit. Doctrine permet une meilleur séparation
mais s'avèrera relativement verbeux pour des cas simples.
Authentification
Pour l'authentification Laravel propose des "starter kits" qui permettent de mettre en
place toutes les opérations classique de gestion de compte utilisateur. Un de ces
starters kits est breeze qui va générer les controllers, models et template blade.
Symfony, quant à lui, dispose d'un composant sécurité qui va permettre de gérer
l'authentification mais n'est pas configuré de base.
// Sur laravel
view('posts/index'); // On fait appelle à une fonction globale
// Sur Symfony
$this->render('posts/index.html.twig') // On fait appelle à une méthode sur le controller
Bien que très différentes, ces 2 méthodes éxécutent un code relativement similaire si
on regarde ce qui se cache derrière :
// Sur Laravel
// view('posts/index');
Container::getInstance()->get('view')->make('posts/index');
// Sur Symfony
// $this->render('posts/index.html.twig')
$this->container->get('twig')->render('posts/index.html.twig')
Dans les 2 cas, le framework va commencer par créer un container qu'il va ensuite
remplir de différents services qui pourront ensuite être récupérés suivant les besoins
au sein de l'application. Laravel se différencie de Symfony par le fait qu'il rende le
container accessible n'importe où dans l'application gràce à l'utilisation d'un
Singleton, là ou Symfony imposera une plus grande rigueur en forçant l'utilisateur à
spécifier les dépendances via un fichier services.yml.
Symfony impose plus de rigueur et est plus proche d'un code PHP classique (à
l'exception de la configuration yaml) et est donc en général plus verbeux. Sa faible
utilisation de méthodes magique permet une meilleur navigation dans le code et une
analyse statique simplifiée.
Au final le choix va surtout dépendre de votre affinité vis à vis de la voix choisie par
ces 2 frameworks pour résoudre la problématique de la création d'application Web.