↓ Aller au contenu
  1. Actualités/

Le Forum PHP 2022 à Disneyland

·2623 mots·13 mins
L’équipe AKAWAKA était au Forum PHP 2022 à Disneyland Paris. Retour sur les conférences qui nous ont le plus marqués, avec pour chacune le replay vidéo.

Thibault Richard (Wid’op) — Un moteur bien huilé
#

Design pattern Rule Engine Symfony

Thibault Richard nous présente le design pattern Rule Engine au travers d’un retour d’expérience chez un client dans le domaine du logement social. Un client qui possède donc un métier complexe avec beaucoup de règles et de traitements différents.

Rule Engine est un système qui évalue un ensemble de règles métiers et détermine les actions à réaliser. Cela permet d’éviter les successions de if / else if dans un algorithme complexe possédant de nombreuses conditions.

Ce modèle est découpé en deux entités : les règles (Rule) et le système qui évalue ces règles, le moteur (Engine).

Ainsi, comme le présente Thibault dans un exemple d’algorithme chargé de lister une collection de documents administratifs à fournir par un demandeur selon ses critères de nationalité, de situation professionnelle, etc. :

Exemple : algorithme conditionnel
public function getDocuments(User $user): array
{
    $documents = [];
    if ($user->isFrench()) {
        $documents[] = new Document('pièce d\'identité');
    } else {
        $documents[] = new Document('titre de séjour');
    }

    if ($user->isEmployee()) {
        ...
    }
}

On peut facilement transformer chaque if en une règle métier telle que :

IdentityRule.php
class IdentityRule implements RuleInterface
{
    public function when(User $user): bool
    {
        return $user->isFrench();
    }

    public function then(User $user): Document
    {
        return new Document('Pièce d\'identité');
    }
}

Enfin, il restera à créer la classe DocumentEngine prenant en paramètre la liste des règles dans un tableau, puis itérer sur chaque règle pour vérifier si lorsque when retourne vrai, alors on appelle then, le traitement de la règle – dans notre exemple si le demandeur est Français, la règle retourne la demande de document “Pièce d’identité”.

Avec Symfony

Thibault nous dévoile comment avec Symfony, il est arrivé facilement à brancher ses règles avec ses moteurs via l’injection de dépendance par tag. Il suffit de taguer les règles puis de les injecter dans un itérateur avec tagged_iterator, voir la documentation Symfony pour en savoir plus.

Notre mise en pratique chez AKAWAKA
#

Cette conférence tombe à pic pour nous chez AKAWAKA. En effet, nous avons actuellement un client qui veut refondre un intranet BtoB possédant un métier très complexe avec beaucoup de conditions.

Nous avons tout naturellement repris ce modèle, cependant, en allant un peu plus loin dans l’implémentation. Nous avons en plus inclus le design pattern spécification qui isole le if dans une classe dédiée, ce qui permet de réutiliser cette condition partout dans notre application.

Enfin, nous avons ajouté du log informatif dans nos moteurs, permettant de suivre les règles qui s’appliquent ou celles qui sont ignorées. Dans un contexte de refonte d’une application vieillissante, cela nous permettra d’identifier les règles qui sont très peu, voire jamais appelées.

WhenUserHasFailureStatus.php
class WhenUserHasFailureStatus implements RuleInterface
{
    public function __construct(
        private DoUserHasFailureStatusInterface $doUserHasFailureStatus
    ) {}

    public function when(User $user): bool
    {
        return $this->doUserHasFailureStatus->isSatisfiedBy($user);
    }

    public function then()
    {
        ...
    }
}
AbstractEarlyRuleEngine.php
abstract class AbstractEarlyRuleEngine implements RuleEngineInterface
{
    private iterable $rules = [];
    private InstrumentationInterface $instrumentation;

    public function __construct(
        iterable $rules,
        InstrumentationInterface $instrumentation
    ) {
        $this->rules = $rules;
        $this->instrumentation = $instrumentation;
    }

    /**
     * @throws RuleEngineException
     * @throws RuleException
     */
    public function __invoke($subject)
    {
        $this->instrumentation->start($this);

        /** @var RuleInterface $rule */
        foreach ($this->rules as $rule) {
            if ($rule->when($subject)) {
                $this->instrumentation->match($this, $rule);
                try {
                    $result = $rule->then($subject);
                    $this->instrumentation->success($this, $rule, $subject);

                    return $result;
                } catch (\Exception $exception) {
                    $this->instrumentation->error($this, $rule, $subject, $exception->getMessage());
                    throw new RuleException($exception->getMessage(), $exception->getCode(), $exception);
                }
            } else {
                $this->instrumentation->skip($this, $rule);
            }
        }

        return null;
    }
}

Avec le service Instrumentation qui va se charger de loguer les interactions en allant piocher dans nos classes de règle et de moteur du contexte via une méthode getDescription. Ce qui donne au final :

Sortie Monolog
[2022-10-21T14:56:47.044789+00:00] app.INFO: security.user_verification.rule_engine.start {"engine":"User verification depends specific rules"} []
[2022-10-21T14:56:47.044874+00:00] app.INFO: security.user_verification.rule_engine.skip {"rule":"When A, then a"} []
[2022-10-21T14:56:47.044941+00:00] app.INFO: security.user_verification.rule_engine.match {"rule":"When B, then b"} []
[2022-10-21T14:56:47.044998+00:00] app.INFO: security.user_verification.rule_engine.success {"rule":"When B, then b","data":{"user":"00012345"}} []

Replay
#


Sarah Haïm-Lubczanski (Bedrock) — Sauve un-e dév, écris une doc !
#

Documentation Diátaxis

La documentation d’une application, son fonctionnement, son code a toujours été un sujet compliqué. Quoi documenter ? Comment présenter cette documentation ? Tout un tas de questions auxquelles Sarah Haïm-Lubczanski tente de répondre dans sa conférence.

Elle nous liste des conseils, des outils et des exemples très pertinents, mais aussi ce qu’il ne faut pas faire ; non, la documentation dans le code n’est pas une bonne documentation.

Elle s’appuie sur le framework Diátaxis qui range, selon le niveau de maîtrise et d’attente du lecteur, les types de documentations possibles :

  • les tutoriels (orientés apprentissage) ;
  • les guides (orientés réalisation) ;
  • les explications (orientées compréhension) ;
  • les références (orientées information technique).

Quant à la forme, des outils permettent de savoir comment bien présenter et tenir une documentation, tels que Write the Docs qui est une documentation sur la manière d’écrire de la documentation, ou bien readme-checklist qui est une checklist aidant à bien rédiger votre README.

Enfin, elle nous prévient cependant que vouloir faire des documentations dynamiques avec une UX avancée à la Stripe demande du temps et des ressources. Chez Stripe, c’est une équipe de 30 développeurs / rédacteurs qui sont à l’œuvre. De plus, une documentation, ça doit être chéri. Il faut la garder à jour, l’enrichir d’exemples, d’images et de schémas quand c’est pertinent.

En bref

En bref, une bonne documentation est un outil qui fait gagner du temps, mais il faut respecter quelques règles pour que celle-ci soit utile. Alors pourquoi ne pas prendre tout de suite les bons réflexes ?

Replay
#


Pierre Tondereau (Mention) — Une extension PHP rouillée
#

Rust Extension PHP Redis

Dans cette conférence, Pierre Tondereau nous présente un REX de création d’extension en Rust.

De par ses grandes performances (proches du C) et sa syntaxe digne d’un langage de haut niveau, Rust est un allié de choix.

Il intègre sur son projet la gestion d’algorithme redlock sur Redis via une extension qu’il a conçue : ext-redlock-php. PHP grâce au FFI peut exécuter du C et donc du Rust.

L’intégration est simplifiée pour les extensions grâce à ext-php-rs. Ce package a pour but de rendre la création d’extension plus simple grâce à la documentation fournie de Rust, ses fonctionnalités modernes, tout en permettant une gestion plus large de versions PHP. Puisque le code Rust est transformé, il va être capable de fonctionner en versions PHP plus anciennes et futures selon le support de l’extension.

Replay
#


Mathias Arlaud (Les-Tilleuls.coop) — De l’humain à l’ordinateur, ou découvrir le sens d’un texte avec Elasticsearch
#

Elasticsearch Apache Lucene Recherche

Mathias Arlaud nous a montré à travers sa conférence comment Elasticsearch (grâce à Apache Lucene) pouvait, à partir d’un simple mot, effectuer une recherche intelligente sur tout un ensemble de documents.

Cette équation peut faire peur, mais Mathias a su nous l’expliquer en la simplifiant sous la forme :

Sd = (TF × IDF) × C

Où :

  • TF représente le termFrequency. C’est-à-dire le nombre de fois où le mot recherché est présent dans les documents stockés dans Elasticsearch.
  • IDF représente l’inverseDocumentFrequency, qui va déterminer si oui ou non le mot d’une phrase recherchée est pertinent.
  • C représente le coordinationFactor. Ce facteur de coordination va mettre en avant les documents contenant le plus haut pourcentage de mots présents dans la phrase recherchée.

Seulement cette formule ne suffit pas à obtenir des résultats pertinents. En effet, Elasticsearch va venir appliquer un traitement en trois étapes au moment de la recherche.

  1. 1

    Les filtres de caractères

    Ils auront la responsabilité d’ajouter, de modifier ou de supprimer des caractères de la phrase recherchée en fonction de règles prédéfinies (pattern_replace, html_strip, etc.).
  2. 2

    Les générateurs de tokens

    La recherche Elasticsearch ne se base pas sur des mots, mais sur des token. Elasticsearch va donc utiliser des générateurs pour découper la requête en tokens.
  3. 3

    Les filtres de tokens

    Ils vont venir agir sur ces tokens pour les modifier. Il en existe plusieurs, dont :

    • stopword qui permet de supprimer tous les tokens inutiles tels que le, la, les
    • stemmer qui va appliquer une série de règles, afin d’obtenir la forme dite “canonique” d’un token, les regroupant ainsi selon cette forme. Par exemple, si nous appliquons ce filtre aux tokens suivants : développement, développeur et développeuse nous obtiendrons développ, développ et développ.

Pour conclure, Mathias Arlaud a su nous ouvrir les portes d’Elasticsearch et d’Apache Lucene pour nous montrer comment, à partir d’une “simple” équation et de quelques outils, Elasticsearch réalise ses recherches de manière intelligente.

Replay
#


Amélie Abdallah (TheTribe) — Comment être bien onboardée en tant que développeuse junior reconvertie ?
#

Onboarding Reconversion Juniors

Amélie Abdallah nous a raconté son histoire de développeuse reconvertie. À travers cette conférence, elle souhaitait faire passer un message à toutes les entreprises présentes.

Recruter des profils en reconversion et donc junior !

Lors de son parcours pour devenir une développeuse accomplie, Amélie est passée par des obstacles :

  • une entreprise pas disponible pour l’aider dans son apprentissage
  • une pression due à sa reconversion
  • une alternance à ne pas louper
  • commencer à coder le premier jour sans soutien ni documentation à l’appui

Pour surmonter ces obstacles, elle a décidé de changer d’entreprise et ce fut une idée qu’elle ne regretta pas. Nouvelle boîte, nouvel accueil, nouveaux collègues, nouvelle façon de faire.

C’est là qu’elle a découvert :

  • une toute nouvelle procédure d’encadrement
  • une présentation de toute l’équipe
  • la découverte de tous les métiers
  • une formation complète aux bonnes manières de coder
  • que coder le premier jour n’est pas bénéfique à l’apprentissage

En conclusion, dans cette nouvelle entreprise, elle a eu tous les outils nécessaires pour débuter sa nouvelle carrière de développeuse.

Le message

Aujourd’hui, elle est épanouie dans ce qu’elle fait et elle souhaite que chaque développeur junior ait la chance d’avoir un accompagnement comme le sien.

Replay
#


Pierre Pelisset (KaraFun) — FFI : de nouveaux horizons pour PHP
#

FFI C RS-232

C’est lors du développement de leur solution de box karaoké que Pierre Pelisset et son équipe ont été confrontés à un dilemme : continuer à utiliser une librairie Python (PySerial), qui posait des soucis techniques et n’est plus mise à jour depuis 2020 ? Ou bien utiliser pleinement PHP et ses fonctionnalités pour communiquer directement sur les ports RS-232 des box ? C’est cette seconde solution qui a été choisie et Pierre nous a présenté FFI (disponible depuis la 7.4), et fait un retour d’expérience de son usage au travers de quelques cas simples mais concrets.

FFI permet donc de pouvoir utiliser au sein de son code PHP d’autres langages. D’exploiter leurs spécificités. Sans rentrer dans des détails trop techniques ici, il s’agit de pouvoir utiliser des bibliothèques compilées (.dll sous Windows ou .so sous Linux) en les chargeant dans notre contexte PHP grâce à C et quelques définitions.

Pour résumer, nous devons écrire un simple header en C contenant les définitions des méthodes que nous utiliserons ensuite. Puis nous chargeons ce header et la librairie associée, rédigeons une sorte de mapping entre les types C et nos types PHP (grâce à des méthodes spécifiques à FFI), puis une ou des classes qui vont intégrer les appels aux méthodes de la librairie.

En production

Selon les retours de Pierre, nous pouvons utiliser FFI en production. C’est ce qu’ils font pour remplacer leur code Python et pouvoir directement communiquer sur les ports RS-232 en PHP. Toutefois FFI ajoute une couche supplémentaire qui, selon les cas, peut poser des soucis de performance. L’usage doit donc être réfléchi et le gain notable pour basculer dessus. De même que quelques notions en C sont nécessaires (pour l’écriture des headers et le typage), même si ce sont des notions assez basiques (pointeurs, etc.).

FFI est une solution intéressante qui peut mériter que l’on s’y penche dans certains cas (souvent des environnements multi-langages ou ayant des besoins très spécifiques). Il ouvre le champ des possibles à PHP en plus de rattraper, une fois de plus, son retard sur d’autres langages de programmation qui intègrent FFI depuis de nombreuses versions.

Du TensorFlow depuis PHP devient alors possible… sans extension 🙂

Replay
#


Anne-Laure de Boissieu (Bedrock) — Revue de code : on n’est pas venu pour souffrir !
#

Code review Conventional Comments

Ayant intégré Bedrock il y a de cela quelques mois à peine, Anne-Laure de Boissieu était quelque peu anxieuse quant aux retours qu’elle pourrait avoir lors de ses merge requests. En effet, un malentendu à l’écrit peut arriver (et nous est tous déjà arrivé au moins une fois). Un commentaire anodin peut alors avoir un impact bien plus important que ce que l’on imaginait auprès de son interlocuteur, selon la tournure de phrase choisie, les mots employés, etc.

Mais Anne-Laure a découvert un cadre rassurant qui permet d’éviter ce genre de déboires. L’équipe se base sur les Conventional Comments afin de normaliser les réponses (dans la même idée que les Conventional Commits pour nos commits), expliciter l’intention et éviter au maximum toute forme de malentendu sur les reviews.

Le résultat final permet une prise de confiance et un onboarding facilité selon elle. Tout en améliorant la qualité globale du projet grâce à une communication saine et sans ambiguïté (ou tout du moins réduite au minimum). Ce à moindres frais puisque l’adoption de cette règle est facilitée par l’existence d’extensions de navigateur (sous Chrome et Firefox).

Un pas de plus vers une communication bienveillante au sein des équipes.

Replay
#


Andreas Heigl (stella-maris.solutions) — Watch the clock
#

Tests PSR-20 Clock

Dans sa conférence, Andreas Heigl nous parle de temps et de comment le maîtriser, notamment lors de tests. En effet, la fonction time() en PHP est une fonction impure et donc elle ne renvoie pas toujours la même valeur. Un code qui utilise cette fonction est difficilement testable, car son résultat peut varier.

Pour pallier ces soucis, Andreas nous propose d’utiliser une interface pour récupérer le temps dans nos applications.

Psr/Clock/ClockInterface.php
<?php

namespace Psr\Clock;

interface ClockInterface
{
    /**
     * Returns the current time as a DateTimeImmutable Object
     */
    public function now(): \DateTimeImmutable;

}

Comme l’espace de noms l’indique, cette interface est une PSR (la PSR-20), celle-ci est actuellement en brouillon.

L’interface peut ensuite être implémentée pour renvoyer le “vrai” temps ou alors pour renvoyer un résultat déterministe pour nos tests.

À retenir

Cette solution permet d’isoler les appels aux fonctions impures. Finis les tests flaky !

Replay
#


Sebastian Bergmann (thePHP.cc) & Roman Pronskiy (JetBrains) — The PHP Foundation: The past, the present, and the future
#

PHP Foundation Communauté

PHP, malgré son long historique, n’avait pas de fondation officielle avant 2021. Le besoin est apparu rapidement en raison du bus factor, mais s’est amplifié, notamment à cause du départ de Nikita Popov. Il arrête d’investir du temps dans PHP pour se consacrer à LLVM au 1er décembre 2021. De nombreuses organisations se sont jointes afin de lancer officiellement la PHP Foundation dans le but de maintenir la pérennité du langage.

L’usage des fonds est public et sert à missionner des développeurs, à temps plein ou occasionnellement. Elle ne vise pas à prendre un monopole décisionnel, ne souhaite pas s’impliquer dans les RFC et laisse à la communauté PHP Internals les décisions d’évolution du langage.

À retenir

On retiendra de la conférence qu’il est important que les entreprises qui utilisent tous les jours ce langage contribuent à sa pérennité.

Replay
#


Forum PHP 2022 — Le mot de la fin
#

Un grand merci à l’AFUP d’avoir organisé ce forum exceptionnel.

Retrouvez l’ensemble des conférences ici.

Des règles métier complexes à modéliser ?

Rule Engine, design patterns, tests déterministes : nos experts Symfony conçoivent des applications métier robustes et maintenables.
Découvrir notre expertise Symfony