Ce que vous devez retenir de SymfonyWorld 2020 2/2

Le rendez-vous majeur de l’écosystème Symfony avait lieu ces jeudi 3 et vendredi 4 décembre et nous y étions.

Voici maintenant notre retour sur la seconde journée – retrouvez ici notre article sur le premier jour si vous ne l’avez pas encore consulté !

Dropping ACID: Schema design for e-commerce

Andreas Braun, qui travaille chez MongoDB, nous a fait réfléchir sur notre façon de stocker des données. Faut-il tout normaliser, et ainsi respecter les formes normales ? Ou faut-il à l’inverse tout dénormaliser et stocker la donnée en tant que document JSON ?

Il faut aussi savoir où stocker la donnée. Il recommande l’un des moteurs suivant : MySQL (le populaire), PostgreSQL (l’outsider), et MongoDB (l’alternative).

Mais avant de choisir un moteur de base de données, il faut regarder ce dont nous avons besoin :

  • SQL vs NoSQL ;
  • Donnée tabulaire vs Donnée riche ;
  • Performance ou Durabilité ;
  • Auto-hébergé ou Cloud ?

Et par extension, voulons-nous utiliser des structures de données Embed (comme avec Doctrine) ou à l’inverse, utiliser des références (Foreign Key) ?

Pour répondre à ces questions, il faut regarder ses données. Cependant, lors de la dernière partie de son talk, Andreas nous explique que nous n’avons pas forcément à choisir. Il nous démontre qu’avec MongoDB, ces problématiques n’existent plus.

Cela étant dit, nous préférons garder nos distances avec MongoDB, et si vous nous lisez régulièrement, vous savez que notre cœur penche vers 💛 PostgreSQL 💛 pour stocker nos données.

Internationalize a Symfony application, the right way

Mathieu a eu l’opportunité de parler des bonnes pratiques à mettre en place pour internationaliser une application Symfony.

Voici en quelques mots les bonnes pratiques qu’il recommande :

  • Penser à l’internationalisation de votre application dès le départ, même si vous ne visez qu’un pays et qu’une langue. La centralisation des textes de votre interface dans les fichiers de traduction sera un confort pour plus tard ;
  • Utiliser XLIFF comme format pour les fichiers de traduction. Oui, ce format est verbeux mais il est le plus complet et est supporté par Symfony et par la grande majorité des systèmes de gestion de traductions (Loco, Transifex, Crowdin, Lokalise, …) ;
  • Installer php-translation/symfony-bundle pour bénéficier de l’ajout de nouvelles clés de traduction via le Profiler de Symfony, mais également des commandes translation:download et translation:sync pour récupérer et synchroniser vos traductions avec votre SaaS sur tous vos environnements ;
  • Ajouter ce crontab sur tous vos environnements */15 * * * * bin/console translation:download --env=prod, ainsi vos traductions seront déployées automatiquement toutes les 15 minutes partout !

Workflow internationalisation

Et pour le « One more thing », Mathieu a ouvert une Pull Request afin d’intégrer les Translations Providers dans le core de Symfony, et permettre de synchroniser vos traductions avec différents SaaS de traduction sans bundle tiers !

Composer 2

Composer 2

Nils Adermann et Jordi Boggiano nous ont présenté Composer 2 et son évolution depuis le début de son développement. Commencée il y a 2 ans, et après avoir mobilisé 28 contributeurs, elle a enfin vu le jour le 24 octobre dernier.

Cette mise à jour avait 3 grands objectifs :

  • La performance ;
  • La reproductibilité et les rapports d’erreurs ;
  • Et rendre l’upgrade la plus simple possible.

Pour ce qui est de la performance, nous avions deux grands coupables aux lenteurs dans Composer : les I/O et le CPU.

Pour les I/O, c’est principalement des problèmes de métadonnées JSON (qui permettent d’identifier les versions compatibles de vos packages avec vos contraintes) et la consommation mémoire qui posaient soucis.

Ensuite, pour le CPU, c’est principalement l’unpack des archives avec ZipArchive qui ralentissait grandement le processus. Désormais, Composer va détecter si vous avez le binaire unzip installé et l’utiliser s’il le peut !

Vous pouvez en lire plus sur tous ces changements dans l’article de blog correspondant.

Ils nous ont aussi partagés quelques-une des nouvelles fonctionnalités qu’apporte Composer 2 :

  • Les updates partielles : composer update org/project:5.0.* va permettre de mettre à jour le package indiqué tout en respectant la version donné (même si la version du composer.json est plus haute normalement) ;
  • Les priorités sur les repositories et la possibilité de filtrer les packages à installer pour un repository custom indiqué.

Enfin, ils nous ont indiqué que pour forcer l’utilisation de Composer 2 sur un projet ou une librairie, il suffit d’ajouter une dépendance à composer-runtime-api en version 2.

Pour finir, nous avons appris que les 500 clients de Private Packagist ont grandement contribué à cette version, mais que cela ne suffit pas encore à couvrir tous les coûts d’infrastructure et de développement.

What I learned trying to make Symfony and API Platform 50% faster

Bastien a déjà eu l’occasion de publier sur ce blog deux billets sur ses optimisations de la stack Symfony (le premier sur l’environnement de prod, et le deuxième sur l’environnement de développement). Sa conférence portait sur la méthodologie et l’outillage pour y arriver afin d’inspirer tout le monde à faire de même sur ses projets et sur les dépendances utilisées.

Cette démarche lui a permis d’optimiser de plus de 60% certaines routes de son application.

Le principe :

  • Utiliser les dernières versions : la performance est vue par les mainteneurs comme une fonctionnalité, et donc comme un argument de vente vers la nouvelle version. Mettre à jour offre souvent un gain de performance, et c’est particulièrement valable pour les versions de PHP, toutes plus performantes les unes que les autres ;
  • Utiliser Blackfire (ou tout autre outil de profiling) pour voir exactement où dans le code la requête passe et prend le plus de temps. Blackfire Player aide beaucoup à automatiser ce profiling ;
  • Chercher des choses suspectes : du code qui n’est pas censé être appelé ou une cardinalité trop haute ;
  • Modifier le code dans les dépendances, lancer un nouveau profil. Itérer ;
  • Si gain trouvé, publier une pull request, sinon créer un ticket pour montrer le soucis et attendre que quelqu’un vienne aider.

À vos profiles !

Why 0.1 + 0.2 != 0.3, or the mysterious world of floating-point numbers

Lisez attentivement cet extrait de code :

$sum = .1 + .2
var_dump($sum) // .3
var_dump($sum == .3) // false 

« Pourquoi » devez-vous sûrement vous demander ? La réponse est assez simple finalement !

Un ordinateur n’est pas capable de stocker des floats (nombres réels), alors il utilise un autre mécanisme : des floating point. D’ailleurs, même votre CPU n’ est pas capable non plus, ce n’est pas lié à PHP. Cependant afficher un floating point, ce n’est pas très pratique. Ça ressemble à quelque chose comme 1234 × 10^-4. Donc pour afficher un floating point, PHP convertit cette valeur en une approximation. Et pour ne pas afficher trop de donnée inutile, PHP s’est doté d’un concept de precision :

php > $a = .3;
php > echo $a;
0.3
php > ini_set("precision", 20);
php > echo $a;
0.2999999999999999889

Nous comprenons maintenant que .1 + .2 != .3.

Lors de ce talk, nous avons appris énormément d’anecdotes intéressantes :

  • la constante PHP_FLOAT_MAX (2.22*10^308) est beaucoup plus grande que PHP_INT_MAX (9.2x10^18). Pourtant, il utilise la même place mémoire ;
  • L’espace des floatings point n’est pas continu : C’est un espace discret ;
  • Il y a un standard pour l’échantillonnage de l’espace des nombres à virgule flottante: IEEE 754 ;
  • Plus le nombre est grand, plus l’écart avec la réalité sera grand lors d’une conversion en int ;
  • La première version d’Ariane 5 a explosé à cause de ces problèmes.

Benoit Jacquemont nous a donné des recommandations pour stocker nos nombres. Il existe des cas légitimes où les float sont intéressants (stats, sensor, etc). Mais pour des prix, des dimensions, il nous recommande d’utiliser des integer (en centimes, en mm). L’utilisation de string, combinée avec des extensions comme bcmath, gpm, ou decimal est aussi intéressante car il n’y a plus de limites. Finalement, certains moteurs de base de données supportent le type decimal. C’est presque comme un floating point, sauf que le point est fixe.

With Symfony 4.4, your secrets will be well kept!

Grégoire Hébert, CTO de les-tilleuls.coop nous a dévoilé quelques secrets de Symfony.

Saviez-vous que Symfony était capable de générer des clés de chiffrement ?

bin/console secrets:generate-keys

Cette commande va générer une paire de clés, une privée et une publique, pour l’environnement de développement. Pour l’environnement de production, ajoutez simplement --env=prod. Il vous faudra l’extension PHP Sodium afin de pouvoir générer ces clés, si vous avez une version de PHP < à 7.2.

Ces clés seront stockées dans le dossier config/secrets/{ENV}/. Attention à vos clés privées {ENV}.decrypt.private.php, elles ne doivent pas être versionnées !

Maintenant que vous avez une clé de chiffrement (publique) et une clé de déchiffrement (privée), vous pouvez chiffrer vos secrets (mots de passe de bases de données, clés d’API externes, token « Remember Me », …) avec la commande suivante :

bin/console secrets:set DATABASE_PASSWORD

Le prompt vous demandera alors de taper la valeur de votre secret, ensuite elle sera chiffrée puis stockée dans un nouveau fichier dans le dossier config/secrets/{ENV}/. Pour utiliser ce secret dans votre code, faites comme si c’était une variable d’environnement :

doctrine:
    dbal:
        password: '%env(DATABASE_PASSWORD)%'

Il nous a également rappelé que SHA1 est désormais considéré comme « faible », puisque selon une étude, en 2019, le coût matériel et le temps nécessaire pour casser une chaîne SHA1 étaient assez bas pour considérer cet algorithme comme obsolète.

WebAuthn dans un projet Symfony

L’intervention de Stefan Richter portait sur un protocole d’authentification que nous surveillons de près mais que nous voyons malheureusement que trop rarement implémenté sur les sites web que nous visitons : WebAuthn.

L’utilisation de mot de passe pose de nombreux problèmes :

  • réutilisation du même mot de passe sur plusieurs sites ;
  • résistance au hack proportionnelle à la difficulté de mémorisation ;
  • renouvellement parfois forcé et contraignant pour les utilisateurs…

80% des problèmes de sécurité sur le Web seraient liés aux mots de passe. Tous ces problèmes sont résolus avec les tokens de sécurité.

Après nous avoir expliqué la spécification et comment nous devons implémenter une telle authentification dans nos projets, Stefan nous a parlé de deux bundles :

  • madwizard/webauthn-bundle : fonctionnel mais très orienté 2FA (authentification à deux facteurs) ;
  • web-auth/webauthn-symfony-bundle : très complet, il embarque des routes prédéfinies, de nouvelles entités, est accompagné d’un paquet NPM… C’est la recommandation de Stefan.

Bundle Webauthn recommandé

WebAuthn est souvent perçu comme un second facteur d’authentification, mais il est parfaitement pertinent en facteur unique. Une des craintes qui oppose de la résistance à son adoption par le grand public est sans doute liée aussi à la peur de perdre la clé physique associée. Mais comme il est possible de perdre un mot de passe, mettre en place une procédure de récupération de compte est très similaire et nécessite donc seulement de posséder une clé de remplacement.

What’s new in PHP 8.0?

Pour la première fois dans un événement Symfony, nous avons eu la chance d’assister à une présentation de Nikita Popov ! Nikita est contributeur à temps plein sur PHP et il a porté un bon nombre des nouveautés de cette version 8.

PHP 8

Cette nouvelle version de PHP, tout juste sortie, est pleine de bonnes choses que nous avons hâte d’appliquer dans nos projets :

  • Le JIT (Just in time compilation), qui donne des améliorations de performances dans certains cas (par exemple, dans une utilisation classique de Symfony cela ne donne aucun avantage visible) ;
  • Nous en avions déjà parlé : Les attributs sont arrivés. Ce que nous appelons des annotations peuvent maintenant être remplacé par des Attributs natif ;
  • Les Propriétés déclarées dans le constructeur permettant d’écrire moins de code « boilerplate » ;
  • Les arguments nommés pour pouvoir « sauter » des argument facultatifs ;
  • Les types joints pour donner plusieurs type à un argument ou une propriété ;
  • L’expression match qui va remplacer switch dans beaucoup de cas ;
  • throw qui devient une expression ;
  • L’opérateur null-safe pour faire des appels chaînés robustes ;
  • Et plus encore !

Nous recommandons la lecture de What’s new in PHP 8 pour un tour d’horizon complet des nouveautés (excellent blog au passage !).

Du côté des breaking changes, certains « Warning » sont devenus des exceptions de type « Error », quand il s’agissait de problèmes réels de développement ou de type notamment.

Conférence en ligne et conclusion

Les conférences en ligne ont toujours un goût particulier et nous avons hâte de pouvoir à nouveau partager et échanger sur nos métiers IRL.

La plateforme utilisée pour organiser SymfonyWorld, Hopin.com n’était pas exempte de problèmes techniques et d’utilisabilité (plein écran impossible sans hack, problème de focus, de sous-titre, les questions mélangées au chat général, des notifications qui apparaissent par dessus le chat le rendant illisible, …). Finalement, nous avons pu assister à des sujets de grande qualité mais nous ne recommanderions pas cet outil pour de futures conférences.

Pour terminer la journée, de nombreuses nouvelles conférences ont été annoncées – toutes en ligne et dans différentes langues – et la SymfonyCon Paris 2021 se déroulera bien à Disneyland !

Bravo à l’équipe Symfony et à tous les speakers, et à la prochaine !

Nos formations sur le sujet

  • Logo Symfony

    Symfony

    Formez-vous à Symfony, l’un des frameworks web PHP les plus connus au monde

  • Logo Symfony avancée

    Symfony avancée

    Décou­vrez les fonc­tion­na­li­tés et concepts avan­cés de Symfo­ny

blog comments powered by Disqus