Programmation PHP avec Symfony/Composant

DescriptionModifier

Le framework Symfony permet nativement les fonctionnalités minimum dans un souci de performances, à l'instar d'un micro-framework. Par exemple son compilateur permet d'utiliser plusieurs patrons de conception (design patterns) via des mots réservés dans services.yaml :


Toutefois, on peut lui ajouter des composants[2], dont il convient de connaitre les fonctionnalités pour ne pas réinventer la roue. Pour les installer :

composer require symfony/nom_du_composant

Les quatre premiers ci-dessous sont inclus par défaut dans le microframework symfony/skeleton.

framework-bundleModifier

Structure la configuration principale du framework sans laquelle aucun composant n'est installable[3].

consoleModifier

Patrons de conception "Commande".

Fournit la possibilité d'exécuter le framework avec des commandes shell[4]. Par exemple pour obtenir la liste de toutes les commandes disponibles dans un projet :

php bin/console help list

dotenvModifier

Gère les variables d'environnement non versionnées, contenues dans un fichier .env[5]. Elles peuvent aussi bénéficier de type checking en préfixant les types avec ":". Ex de .env :

IS_DEV_SERVER=1

Le services.yaml, parameters: récupère ensuite cette valeur et vérifie qu'il s'agit d'un booléen (via le processeur de variable d'environnement "bool") :

is_dev_server: '%env(bool:IS_DEV_SERVER)%'

Il existe plusieurs processeurs de variable d'environnement (en plus de "bool" et des autres types)[6] :

  • base64: encode en base64.
  • default: remplace le deuxième paramètre par le premier si absent. Ex :
    • $addTestValues: '%env(bool:default::ADD_TEST_VALUES)%' injecte "null" si ADD_TEST_VALUES n'est pas défini.
    • $addTestValues: '%env(bool:default:ADD_TEST_VALUES2:ADD_TEST_VALUES1)%' injecte le contenu de ADD_TEST_VALUES2 si ADD_TEST_VALUES1 n'est pas défini.
  • file: remplace le chemin d'un fichier par son contenu.
  • not: renvoie l'inverse.
  • require: fait un require() PHP.
  • resolve: remplace le nom d'une variable par sa valeur.
  • trim: fait un trim() PHP.

Pour définir une valeur par défaut en cas de variable d'environnement manquante (sans utiliser default:), dans services.yaml, parameters: :

env(MY_MISSING_CONSTANT): '0'

yamlModifier

Ajoute la conversion de fichier YAML en tableau PHP[7]. Ce format de données constitue une alternative plus lisible au XML pour renseigner la configuration des services. Par défaut le framework se configure avec config.yaml.

routingModifier

patron de conception "Façade".

Installe les annotations permettant de router des URLs vers les classes des contrôleurs MVC.


Pour plus de détails voir : Programmation PHP/Symfony#Routing.

serializerModifier

Permet de convertir des objets en tableaux ou dans les principaux formats de notation : JSON, XML, YAML et CSV[8].

 composer require symfony/serializer

Ce composant est notamment utilisé pour créer des APIs.

formModifier

Construit des formulaires HTML.


Pour plus de détails voir : Programmation PHP/Symfony/Formulaire.

validatorModifier

Fournit des règles de validation pour les données telles que les adresses emails ou les codes postaux. Utile à coupler avec les formulaires pour contrôler les saisies.

Ces règles peuvent porter sur les propriétés ou les getters.

Il permet aussi de créer des groupes de validateurs, et de les ordonner par séquences. Par défaut chaque classe a automatiquement deux groupes de validateurs : "default" et celui de son nom. Si une séquence est définie, le groupe "default" n'est plus égal au groupe de la classe (celui par défaut) mais à la séquence par défaut[9].

translationModifier

Module de traductions dans des fichiers contenant le ISO 639-1 de chaque langue du projet. Par défaut le français est dans translations/messages.fr.yml. On peut ensuite récupérer ces dictionnaires en Twig, ou en PHP via le service "translator"[10].

Pour avoir les traductions inutilisées en anglais :

bin/console debug:translation en --only-unused

Pour les traductions manquantes en anglais :

bin/console debug:translation en --only-missing

event-dispatcherModifier

Patrons de conception "Observateur"[11] et "Médiateur"[12].

Assure la possibilité d'écouter des évènements pour qu'ils déclenchent des actions.


Pour plus de détails voir : Programmation PHP/Symfony/Évènement.

processModifier

Permet de lancer des sous-processus en parallèle[13]. Exemple qui lance une commande shell :

    $process = new Process(['ls']);
    $process->run();

 

En l'absence de $process->stop() ou de timeout, le sous-processus peut être stoppé en redémarrant le serveur PHP.

Exemple de requête SQL asynchrone[14] :

        $sql = 'SELECT * FROM ma_table LIMIT 1';
        $process = Process::fromShellCommandline(sprintf('../bin/console doctrine:query:sql "%s"', $sql));
        $process->setTimeout(3600);
        $process->start();

cacheModifier

Gère les connexions, lectures et écritures vers des serveurs de mémoire caches tels que Redis ou Memcached.

Il fournit une classe cacheItem conforme à la PSR, instanciable par plusieurs adaptateurs.

assetModifier

Ajoute la fonction Twig asset() pour accéder aux fichiers CSS, JS ou images selon leurs versions[15].

webpack-encoreModifier

Intégration de Webpack pour gérer la partie front end (ex : minifications des CSS et JS).

Installation[16] :

composer install encore
yarn install
yarn build

NB : si yarn n'est pas installé, le faire avec apt install nodejs npm; npm install --global yarn.

Cela crée les fichiers package.json et yarn.lock contenant les dépendances JavaScript, le dossier assets/ contenant les JS et CSS versionnés, et le fichier webpack.config.js dans lequel ils sont appelés.

De plus, des fonctions Twig permettent d'y accéder depuis les templates : encore_entry_link_tags() et encore_entry_script_tags().

Par ailleurs, cela installe le framework JS Stimulus, et interprète les attributs de données pour appeler ses contrôleurs ou méthodes.

messengerModifier

Patrons de conception "Chaîne de responsabilité".

Messenger permet d'utiliser des queues au protocole AMQP. En résumé, il gère l'envoi de messages dans des bus, ces messages transitent par d'éventuels middlewares puis arrivent à destination dans des handlers[17]. On peut aussi persister ces messages en les envoyant dans des transports via un DSN, par exemple dans RabbitMQ, Redis ou Doctrine (donc une table des SGBD les plus populaires).

 php bin/console debug:messenger

Chaque middleware doit passer le relais au suivant ainsi :

return $stack->next()->handle($envelope, $stack);

Pour stopper le message dans un middleware sans qu'il arrive aux handlers :

return $envelope;

workflowModifier

Patrons de conception "État".

Ce composant nécessite de créer (en YAML, XML ou PHP) la configuration d'un automate fini[18], c'est-à-dire la liste de ses transitions et états (appelés "places").

Ces graphes sont ensuite visualisables en image ainsi :

use Symfony\Component\Workflow\Definition;
use Symfony\Component\Workflow\Dumper\StateMachineGraphvizDumper;

class WorkflowDisplayer
...
$definition = new Definition($places, $transitions);
echo (new StateMachineGraphvizDumper())->dump($definition);
sudo apt install graphviz
php WorkflowDisplayer.php | dot -Tpng -o workflow.png

browser-kitModifier

Simule un navigateur pour les tests d'intégration.

configModifier

Permet de manipuler des fichiers de configurations.

contractsModifier

Pour la programmation par contrat.

css-selectorModifier

Pour utiliser XPath.

debugModifier

Fournit des méthodes statiques pour déboguer le PHP.

dependency-injectionModifier

Normalise l'utilisation du container de services.

Permet aussi d'exécuter du code pendant la compilation via un compiler pass, en implémentant l'interface CompilerPassInterface avec sa méthode process[19].

dom-crawlerModifier

Fournit des méthodes pour parcourir le DOM.

expression-languageModifier

Patrons de conception "Interpréteur".

Expression language sert à évaluer des expressions, ce qui peut permettre de définir des règles métier[20].

Installation :

composer require symfony/expression-language

Exemple :

$el = new ExpressionLanguage();
$operation = '1 + 2';
echo(
    sprintf(
        "L'opération %s vaut %s",
        $el->compile($operation));
        $el->evaluate($operation));
    )
);
// Affiche : L'opération 1 + 2 vaut 3

filesystemModifier

Méthodes de lecture et écriture dans les dossiers et fichiers.

finderModifier

Recherche dans les dossiers et fichiers.

securityModifier

Ensemble de sous-composants assurant la sécurité d'un site. Ex : authentification, anti-CSRF ou droit des utilisateurs d'accéder à une page.

Dans security.yaml, on peut par exemple définir les classes qui vont assurer l'authentification (guard), ou celle User qui sera instanciée après.

Pour obtenir l'utilisateur ou son token, on peut injecter :

TokenStorageInterface $tokenStorage

pour avoir l'utilisateur courant avec $this->tokenStorage->getToken()->getUser().

guardModifier

Extension de sécurité pour des authentifications complexes.

http-clientModifier

Pour lancer des requêtes HTTP depuis l'application.


Pour plus de détails voir : Programmation PHP/Symfony/HttpClient.

http-foundationModifier

Fournit des classes pour manipuler les requêtes HTTP, comme Request et Response que l'on retrouve dans les contrôleurs.

Par exemple :

use Symfony\Component\HttpFoundation\Response;
//...
echo Response::HTTP_OK; // 200
echo Response::HTTP_NOT_FOUND; // 404

http-kernelModifier

Permet d'utiliser des évènements lors des transformations des requêtes HTTP en réponses.

inflectorModifier

Deprecated depuis Symfony 5.

Accorde les mots anglais au pluriel à partir de leurs singuliers.

intlModifier

Internationalisation, comme par exemple la classe "Locale" pour gérer une langue.

ldapModifier

Connexion aux serveur LDAP.

lockModifier

Pour verrouiller les accès aux ressources[21].

Par exemple, pour ne pas qu'une commande soit lancée deux fois simultanément, bien que le composant console aie aussi cette fonctionnalité :

 use Symfony\Component\Console\Command\LockableTrait;
 ...
    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        if ($this->lock() === false) {
            return Command::SUCCESS;
        }

        ...

        $this->release();
        return Command::SUCCESS;
    }

mailerModifier

Pour envoyer des emails.

mimeModifier

Manipulation des messages MIME.

notifierModifier

Pour envoyer des notifications telles que des emails, des SMS, des messages instantanés, etc.

options-resolverModifier

Gère les remplacements de propriétés par d'autres, avec certaines par défaut.

phpunit-bridgeModifier

Patron de conception "Pont" qui apporte plusieurs fonctionnalités liées aux tests unitaires, telles que la liste des tests désuets ou des mocks de fonctions PHP natif.

property-accessModifier

Pour lire les attributs de classe à partir de leurs getters, ou des tableaux.

property-infoModifier

Pour lire les métadonnées des attributs de classe.

stopwatchModifier

Chronomètre pour mesurer des temps d'exécution.

stringModifier

API convertissant certains objets en chaine de caractères. Ex :

use Symfony\Component\String\Slugger\AsciiSlugger;

$slugger = new AsciiSlugger();
echo $slugger->slug('caractères spéciaux € $');

Résultat :

caracteres-speciaux-EUR

templatingModifier

Extension de construction de templates.


Pour plus de détails voir : Programmation PHP/Symfony/Templating.

var-dumperModifier

Ajoute une fonction globale dump() pour déboguer des objets en les affichant avec une coloration syntaxique et des menus déroulant.

Ajoute aussi dd() pour dump() and die().

var-exporterModifier

Permet d'instancier une classe sans utiliser son constructeur.

polyfill*Modifier

On trouve aussi une vingtaine de composants polyfill, fournissant des fonctions PHP retirées dans les versions les plus récentes.

Composants désuetsModifier

locale (<= v2.3)Modifier

Arrêté en 2011, car remplacé par le composant intl[22].

icu (<= v2.6)Modifier

Arrêté en 2014, car remplacé par le composant intl[23].

class-loader (<= v3.3)Modifier

Arrêté en 2011, car remplacé par composer.json[24].

Ajoutés en 2020Modifier

Uid (sic) (>= v5.1)Modifier

Pour générer des UUID[25].

RateLimiter (>= v5.2)Modifier

Patron de conception "Proxy", qui permet de limiter la consommation de ressources du serveur par les clients[26]

Semaphore (>= v5.2)Modifier

Pour donner l'exclusivité d'accès à une ressource[27].

Ajoutés en 2021Modifier

PasswordHasher (>= v5.3)Modifier

Pour gérer les chiffrements[28].

Runtime (>= v5.3)Modifier

Pour le démarrage (bootstrap) : permettre de découpler l'application de son code de retour. [29].

Ajoutés en 2022Modifier

HtmlSanitizer (>= v6.1)Modifier

Clock (>= v6.2)Modifier

Symfony UX (>= v5.4)Modifier

ux-autocompleteModifier

ux-chartjsModifier

Utilise Chart.js via Stimulus pour afficher des graphiques, via la fonction Twig render_chart()[30].

ux-reactModifier

Ajoute le framework React.js.

ux-vueModifier

Ajoute le framework Vue.js.

Ajoutés en 2023Modifier

Webhook et RemoteEvent (>= v6.3)Modifier

[31]

AssetMapper (>= v6.3)Modifier

[32]

Scheduler (>= v6.3)Modifier

[33]

Composants non listés comme telsModifier

apache-packModifier

Pour faire tourner le site sans passer par le serveur symfony server:start.

RéférencesModifier

  1. https://symfony.com/doc/current/service_container/factories.html
  2. https://symfony.com/components
  3. https://symfony.com/doc/current/reference/configuration/framework.html
  4. https://symfony.com/doc/current/components/console.html
  5. https://symfony.com/doc/current/components/dotenv.html
  6. https://symfony.com/doc/current/configuration/env_var_processors.html
  7. https://symfony.com/doc/current/components/yaml.html
  8. https://symfony.com/doc/current/components/serializer.html
  9. https://symfony.com/doc/current/validation/sequence_provider.html
  10. https://symfony.com/doc/current/translation.html
  11. http://www.jpsymfony.com/design_patterns/le-design-pattern-observer-avec-symfony2
  12. https://github.com/certificationy/symfony-pack/blob/babd3fee68a7e793767f67c6df140630f52e7f8d/data/architecture.yml#L13
  13. https://symfony.com/doc/current/components/process.html
  14. https://gist.github.com/appaydin/42eaf953172fc7ea6a8b193694645324
  15. https://symfony.com/doc/current/components/asset.html
  16. https://symfonycasts.com/screencast/stimulus/encore
  17. https://vria.eu/delve_into_the_heart_of_the_symfony_messenger/
  18. https://symfony.com/doc/current/workflow.html
  19. https://symfony.com/doc/current/components/dependency_injection/compilation.html
  20. https://symfony.com/doc/current/components/expression_language.html
  21. https://symfony.com/doc/current/components/lock.html
  22. https://symfony.com/components/Locale
  23. https://symfony.com/components/Icu
  24. https://symfony.com/components/ClassLoader
  25. https://symfony.com/doc/current/components/uid.html
  26. https://symfony.com/doc/current/rate_limiter.html
  27. https://symfony.com/doc/current/components/semaphore.html
  28. https://symfony.com/blog/new-in-symfony-5-3-passwordhasher-component
  29. https://symfony.com/blog/new-in-symfony-5-3-runtime-component
  30. https://symfony.com/bundles/ux-chartjs/current/index.html
  31. https://symfony.com/blog/new-in-symfony-6-3-webhook-and-remoteevent-components
  32. https://symfony.com/blog/new-in-symfony-6-3-assetmapper-component
  33. https://symfony.com/blog/new-in-symfony-6-3-scheduler-component