Thibault Richard (Wid’op) — Un moteur bien huilé#
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. :
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 :
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é”.
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.
class WhenUserHasFailureStatus implements RuleInterface
{
public function __construct(
private DoUserHasFailureStatusInterface $doUserHasFailureStatus
) {}
public function when(User $user): bool
{
return $this->doUserHasFailureStatus->isSatisfiedBy($user);
}
public function then()
{
...
}
}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 :
[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 !#
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, 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#
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#
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
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
Les générateurs de tokens
La recherche Elasticsearch ne se base pas sur des mots, mais sur destoken. Elasticsearch va donc utiliser des générateurs pour découper la requête en tokens. - 3
Les filtres de tokens
Ils vont venir agir sur ces tokens pour les modifier. Il en existe plusieurs, dont :
stopwordqui permet de supprimer tous les tokens inutiles tels quele,la,lesstemmerqui 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éveloppeuretdéveloppeusenous obtiendronsdévelopp,développetdé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 ?#
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.
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#
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.
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 !#
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#
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.
<?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.
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, 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.
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.

