PHP Way of Life

Le Manifeste PHP Way of Life

Ça fait longtemps maintenant que je prône une vision du développement PHP qui utilise les bonnes pratiques de manière intelligente et mesurée, et qui repose sur quelques fondamentaux forts :

  • Si vous voulez faire du Java, faites du Java. Le monde PHP s’est énormément inspiré du monde Java ces 15 dernières années, pour le meilleur et pour le pire.
  • Les bonnes pratiques de Google et Facebook ne peuvent pas être les pratiques dont une startup de 15 personnes a besoin.
  • Rien ne sert d’empiler les technologies juste pour dire qu’on fait les choses « comme il faut ». Il n’y a aucune gloire à créer des systèmes inutilement complexes. Aucune récompense à utiliser un framework JS pour le frontend là où de simples templates serveur répondent parfaitement au besoin.

À force d’expliquer mon point de vue oralement, il m’a paru plus efficace de le mettre par écrit. Je l’ai appelé le Manifeste PHP Way of Life, car pour moi il représente l’essentiel de la philosophie du langage.

Pour y accéder : www.phpwayoflife.com

www.phpwayoflife.com

Les chapitres

Le Manifeste, qui a été publié en anglais uniquement pour le moment, contient 11 chapitres :

  1. Introduction: PHP, the Web’s Language
    Retour sur les raisons qui font historiquement du PHP LE langage du Web, et quelques réflexions sur l’évolution du développement web moderne.
     
  2. Arrays: The preferred way to transfer data, simple and flexible
    Pourquoi les tableaux de PHP sont un outil particulièrement efficace.
     
  3. Objects: Perfect for organizing code, best used with procedural logic
    Une confrontation entre la vision « pur objet » et l’utilisation d’objets avec une approche procédurale.
     
  4. Typing: Strong in principle, adaptable in practice, but never strict
    Quelles sont les forces du système de typage de PHP, et pourquoi le typage strict n’est pas une aussi bonne idée qu’on le pense.
     
  5. Web Interfaces: Server-generated HTML is key to a fast, accessible Internet
    Tout ce qui fait que, pour une interface transactionnelle classique, l’utilisation de frameworks Javascript est une très mauvaise idée.
     
  6. Databases: ORMs and NoSQL look like your friends, but SQL truly is
    Pourquoi l’accès aux données doit rester simple si vous ne voulez pas que ça se retourne contre vous un jour.
     
  7. Frameworks: Good servants but terrible masters
    Sortir de la pensée unique qui ferait croire qu’un ou deux frameworks seraient parfaits dans l’absolu, convenant aussi bien à des équipes de 8 personnes, 80 personnes ou 250 personnes.
     
  8. Automated tests: Unit, integration, functional − Find your balance
    Remettre le curseur au bon endroit, car il n’y a pas que les tests unitaires dans la vie.
     
  9. Micro-services: Highly unlikely you’ll need them
    Encore une approche technique devenue à la mode pour de mauvaises raisons.
     
  10. APIs: Challenge the habits
    Les manières de construire une API sont plus variées que la plupart des gens ne l’imaginent.
     
  11. Security: The Non-Negotiable Basics
    En matière de sécurité, il y a des incontournables, et il faut savoir comment les implémenter intelligemment.
     

Le contenu

Ne croyez pas que le Manifeste n’est alimenté que par mon seul point de vue. J’ai collecté énormément de ressources bibliographiques (plus de 80 références), avec des citations provenant de Rasmus Lerdorf (créateur du langage PHP), David Heinemeier Hansson (créateur du framework Ruby on Rails), Jeff Atwood (co-créateur de StackOverflow et Discourse), Rob Pike (co-créateur du système d’exploitation Plan 9, de l’encodage UTF-8 et du langage Go), Rich Hickey (créateur du langage Clojure), Joe Armstrong (co-créateur du langage Erlang), Gina Banyard (membre de la core team PHP), Adrian Holovaty (co-créateur du framework Django), Michael Stonebraker (co-créateur de la base de données PostgreSQL), Laurie Voss (cofondateur du gestionnaire de paquets NPM), le gouvernement du Royaume-Uni, et beaucoup d’autres.

Le Manifeste ne propose pas juste des titres péremptoires ou énigmatiques. Chaque chapitre est détaillé et argumenté. Le contenu fait 65 pages au format PDF (dont 1 page de table des matières, 1 page de ressources et 5 pages de références).

Il est accessible en plusieurs formats : HTML adapté aux écrans, HTML imprimable, PDF A4 et ePub.

La suite

Le but n’est pas que le Manifeste soit juste un document statique sans suivi, mais bien qu’il s’intègre dans un tout plus grand. J’ai donc d’autres projets en cours, qui gravitent autour du Manifeste d’une manière ou d’une autre.

Pour commencer, beaucoup des idées du Manifeste se concrétisent dans le framework Temma, que j’ai créé il y a 18 ans, et qui a été utilisé par plusieurs entreprises sur plusieurs centaines de sites, certains à très fort trafic (plusieurs dizaines de millions de pages vues par mois).
Temma cherche à trouver le bon équilibre en étant plus simple à apprendre que les gros frameworks connus, et plus utile que les micro-frameworks.

Ensuite, PHP Zen est un projet en cours de réalisation, dont le but est de partager des articles intéressants qui sont alignés avec le PHP Way of Life. Pour le moment, ces articles sont partagés sur des réseaux sociaux (LinkedIn et Instagram).

Et les grincheux ?

Je suis conscient que le manifeste PHP Way of Life peut être assez clivant. En informatique, on est coutumier des guerres de clochers, donc je dois m’attendre à des remarques acerbes de la part de développeurs persuadés de connaître la seule et unique vérité.

‣ Comme ce développeur pour qui le web moderne passait forcément par un framework Javascript, disant que les templates étaient des reliques du passé. Malgré le fait que son site était purement transactionnel, il s’est retrouvé à devoir maintenir des templates Twig + du Vue.js 2 + du Nuxt.js 2 + du Vue.js 3 + du Nuxt.js 3…
‣ Ou cet autre développeur pour qui les ORM sont essentiels, parce qu’il est aujourd’hui inenvisageable de ne pas utiliser des entités. Et à force de manipuler des entités sans se soucier de leur cycle de vie, il avait une page qui faisait 6 000 requêtes SQL…
‣ Ou ce CTO pour qui ne pas utiliser les strict_types est un signe d’amateurisme, mais qui n’a pas le moindre test automatisé sur toute sa base de code…
‣ Ou ce créateur de startup, seul développeur sur son projet, qui s’est lancé dans un développement à base de micro-services. Et qui a fini par abandonner après y avoir consacré beaucoup plus de temps que prévu sans pouvoir sortir son MVP…

Bref, ceux qui me diront que je n’ai rien compris au développement moderne, je pense d’eux la même chose que de ceux qui, il y a 13 ans, me disaient que le PHP ne permet pas de faire de la qualité et n’est pas rentable (et autres joyeusetés).

Tout ça pour dire que je ne ressens pas le besoin de convaincre les gens, juste celui de partager mon expérience et ma vision des choses, parce que ça peut être utile − ne serait-ce que pour alimenter la réflexion. C’est la continuité de ce blog, quelque part.

16 commentaires pour “Le Manifeste PHP Way of Life

  1. Vraiment très intéressant… merci !!

    Plusieurs expériences de ce « genre » de mon côté également (ouf, je me sens moins seul d’un coup !)

  2. Bonjour,

    Je suis tombé presque par hasard sur l’article (google actu) je vais donc laissé un message sûrement unique.

    > « Arrays: The preferred way to transfer data, simple and flexible

    Utiliser un tableau pour faire autre chose qu’un tableau (index séquentiel) ou une hashmap simple c’est ouvrir la porte à un cauchemard de runtime. On y met ce qu’on veut donc surprise lors de l’appel.

    Avec une classe on aurait vu qu’il manque une propriété directement dans l’IDE et par l’interpréteur à l’exécution.

    > Objects: Perfect for organizing code, best used with procedural logic
    > Une confrontation entre la vision « pur objet » et l’utilisation d’objets avec une approche procédurale.

    Le problème de l’exemple est (imo) un faux problème qui est réglé par l’injection de la dépendance FileUtils dans la classe.
    Il y a des composants qui automatisent ça de nos jours. (Symfony DependencyInjection Component)
    D’ailleurs si vous voulez mocker FileUtils facilement dans vos tests je vous conseillerai de faire du DI.

    > Typing: Strong in principle, adaptable in practice, but never strict
    > $result = concat((string)$str1, (string)$str2);
    > It’s clear that, even for such a simple example, the code is more verbose. Reading it requires extra cognitive effort.

    Le vrai problème c’est qu’il manque le typage de variable locale / globale en PHP.
    Si on change l’exemple par
    public string $str1
    public string $str12;

    concat($this->str1, $this->str2) ;

    Pas de problème de type checking pour moi.
    Donc espérons qu’une RFC voit le jour plutôt.

    >Too strict may lead to too lax
    > The perceived need for so called « strict » type casts is a clear symptom that explicit casts are used in places where they shouldn’t be just to comply with the type declaration of a function’s parameter.

    Oui mais comme dit au-dessus je vois ça surtout comme le signe qu’il y a soit un problème de design du code soit que le langage n’a pas encore un support complet suffisant pour du typage strict.

    > Web Interfaces: Server-generated HTML is key to a fast, accessible Internet

    Tout le monde ne peut pas se permettre de faire du hello world. Il y a des applications qui ont besoin d’interfaces riches et réactives.
    Quand je lis « mental overhead of state management on the frontend » je me demande si la personne a déjà vu du code react + redux toolkit où tout est SOLID / DRY contrairement à du vanilla js bien bloated avec une jungle de callbacks.

    > Databases: ORMs and NoSQL look like your friends, but SQL truly is

    Encore une fois si c’est pour maintenir un hello world pas de soucis.
    Si vous avez des dizaines d’entité vous allez finir par réinventer la roue et recréer votre gestion de schéma, d’éxécution de patchs, d’hydratation de votre donnée, de sécurisation de vos requêtes etc.

    Mais en plus de perdre un temps colossal à faire tout ça vous aller le faire mal, vous allez omettre la gestion des caches de metadonnées etc…

    Vous allez aussi souffrir pour factoriser une simple requête SQL avec une autre, alors qu’un QueryBuilder rend ça facile.

    L’exemple des 6000 requêtes est encore une fois un problème d’un développeur qui connait mal son sujet et qui tombe dans un problème bien connu du lazy loading des relations d’une entité. (il y a des solutions faciles et bien documentées pour pallier à ça)

    > Frameworks: Good servants but terrible masters

    Comme pour l’ORM, plus votre projet grandira, plus vous finirez par réinventer la roue et mal qui plus est car concentrés sur le business vous n’aurez pas le temps de développer correctement votre framework pour vous faire gagner suffisamment en productivité, vous laisserez des trous de sécurité plus longtemps contrairement à la communauté opensource et vous ne documenterez et ne testerez qu’une faible partie. (business oblige…)

    > Automated tests: Unit, integration, functional − Find your balance

    Un point sur lequel je suis d’accord, sachant que si vous voulez faire des tests unitaires sans vous arrachez les cheveux, faites de la POO correctement en amont.

    > Micro-services: Highly unlikely you’ll need them

    Deuxième point d’accord (à nuancer selon les besoin de scaling)

    > Authentication: Say Yes to HTTP Basic, No to JWT

    JWT c’est très bien et avec un algo asymétrique svp.

    > La partie securité

    Oui MAIS autant de pain points déjà pris en charge par un ORM et/ou un framework même si ça ne dispense pas de les connaitre et d’y faire attention.

    > Et les grincheux ?
    > En informatique, on est coutumier des guerres de clochers, donc je dois m’attendre à des remarques acerbes de la part de développeurs persuadés de connaître la seule et unique vérité.

    Ça ne sert à rien d’affubler de qualificatifs péjoratifs ceux qui ne sont pas d’accord avec votre vision « intelligente et mesurée ». Les mainteneurs et tous les professionnels qui font et utilisent PHP au quotidien ont aussi une expérience qui les a conduits à penser PHP et son écosystème différemment de votre vision.

    > Tout ça pour dire que je ne ressens pas le besoin de convaincre les gens, juste celui de partager mon expérience et ma vision des choses, parce que ça peut être utile − ne serait-ce que pour alimenter la réflexion. C’est la continuité de ce blog, quelque part.

    Je n’ai pas du tout été convaincu mais lire une approche différente permet toujours de remettre mes convictions en question, et puis ce n’est pas tous les jours qu’on peut argumenter sur PHP. kudos.

  3. Php n’était pas une bonne idée en 2000, on n’a même plus l’excuse du nombre de suiveurs de cette daube moribonde en 2025. Mais continuez à vous trouvez des excuses pour votre typage pourri.

  4. 100% d’accord d’ailleurs on revient progressivement à cette simplicité car elle convient dans la majorité des cas 🙂

  5. @Cyril Merci beaucoup pour ton long commentaire (et heureux de savoir que mon article a été proposé par Google Actu).

    Utiliser un tableau pour faire autre chose qu’un tableau (index séquentiel) ou une hashmap simple c’est ouvrir la porte à un cauchemard de runtime. On y met ce qu’on veut donc surprise lors de l’appel.

    L’idée n’est pas de dire qu’il ne faut jamais utiliser d’objets. Mais si ton réflexe est de créer une DTO pour transférer la moindre donnée, tu peux renverser le rapport lisibilité/maintenabilité.

    Le problème de l’exemple est (imo) un faux problème qui est réglé par l’injection de la dépendance FileUtils dans la classe.

    Pas d’accord, ça n’a rien à voir avec l’injection de dépendance. Aucun souci avec l’injection de dépendance en général. Là c’est vraiment l’approche purement orientée objet qui est moins lisible qu’une approche un peu plus procédurale, où tu peux facilement suivre chaque exécution ligne à ligne.

    Pas de problème de type checking pour moi.
    Donc espérons qu’une RFC voit le jour plutôt.

    Là j’ai cité la RFC de Gina Banyard (membre de la core team PHP). C’est un peu couillu de la balayer de la main.
    On en revient à un principe de base : si tu veux faire du Java, fais du Java.

    Tout le monde ne peut pas se permettre de faire du hello world. Il y a des applications qui ont besoin d’interfaces riches et réactives.

    On est d’accord, les vraies applications web comme Deezer ou Google Docs ont besoin d’un framework front solide.
    Mais de là à dire que tout ce qui ne tombe pas dans ce cas est du Hello World, c’est un peu facile. Il existe une écrasante majorité de sites web qui sont purement transactionnels (on clique sur des liens pour charger des pages, on envoie des formulaires), qui n’utilisent strictement aucune réactivité poussée dans leur interface, et qui n’ont aucun besoin d’un framework JS qui nuit à la rapidité et à l’accessibilité.

    Quand je lis « mental overhead of state management on the frontend » je me demande si la personne a déjà vu du code react + redux toolkit où tout est SOLID / DRY contrairement à du vanilla js bien bloated avec une jungle de callbacks.

    Disons qu’entre du React + Redux (+ tout le reste qui change tous les 6 mois) et du Vanilla JS, il y a quand même tout un monde.
    Je cite des exemples comme Basecamp, qui utilise Turbo pour dynamiser un site fait en Ruby on Rails, sans passer par un framework front pour autant.
    Il y a quand même un élan de simplification avec des technos comme Turbo (utilisé dans Symfony UX, notamment), htmx, AlpineJS, etc.

    Encore une fois si c’est pour maintenir un hello world pas de soucis.

    Let’s agree to disagree.
    Ce que tu dis me fait penser à un formateur Java que j’ai croisé dans un organisme de formation (où je donnais des formations PHP), et qui me soutenait que les langages de script (PHP, Python, Ruby, tous dans le même sac) ne servaient qu’à faire des petits sites perso, et que les vrais sites ne pouvaient être développés qu’en Java.

    L’essence même du Manifeste est de dire qu’il faut sortir de la pensée unique.

    Vous allez aussi souffrir pour factoriser une simple requête SQL avec une autre, alors qu’un QueryBuilder rend ça facile.

    Pas d’accord non plus. Je donne un exemple dans le Manifeste, qui montre qu’un query builder n’est pas plus clair qu’une requête SQL. Et il y a des cas pour lesquels tu ne pourras pas utiliser de query builder. Il est important de connaître le SQL. À force de ne manipuler que des entités, on fait n’importe quoi.

    L’exemple des 6000 requêtes est encore une fois un problème d’un développeur qui connait mal son sujet et qui tombe dans un problème bien connu du lazy loading des relations d’une entité. (il y a des solutions faciles et bien documentées pour pallier à ça)

    Le truc, c’est que dans la vraie vie on a des équipes qui ont du turn-over, avec des développeurs et développeuses qui ont des niveaux très disparate. Donc les technologies qui nécessitent de l’expertise poussée pour ne pas se générer de la dette technique de manière exponentielle, c’est vraiment un flingue pointé vers ton pied (et on attend qu’un petit nouveau tire sur la détente).
    Après, si toi tu as toujours travaillé avec une équipe stable de dévs séniors qui connaissent toutes les choses à faire et à ne pas faire pour que ça fonctionne, c’est top.

    Comme pour l’ORM, plus votre projet grandira, plus vous finirez par réinventer la roue et mal qui plus est car concentrés sur le business vous n’aurez pas le temps de développer correctement votre framework pour vous faire gagner suffisamment en productivité, vous laisserez des trous de sécurité plus longtemps contrairement à la communauté opensource et vous ne documenterez et ne testerez qu’une faible partie. (business oblige…)

    Le message n’est pas qu’il ne faut pas utiliser de framework. Mais plutôt de sortir de la pensée unique Symfony (en France) ou Laravel (aux États-Unis), qui laisserait croire que ce sont les seuls qui valent la peine.
    Il existe tout un éventail d’outils qui peuvent répondre aux besoins.

    Un point sur lequel je suis d’accord, sachant que si vous voulez faire des tests unitaires sans vous arrachez les cheveux, faites de la POO correctement en amont.

    Oui, et j’insiste sur le fait que si on n’a que des tests unitaires, on prend des risques. Panacher avec des tests d’intégration permet de couvrir des zones d’ombre (les cas où les tests unitaires sont au vert mais que ça ne fonctionne pas bien quand on met tout ensemble) ; ça peut faire gagner du temps (dans l’écriture des tests) et peut être plus facile à maintenir (et donc gagner encore du temps en définitive).

    Deuxième point d’accord (à nuancer selon les besoin de scaling)

    Bah j’attend les exemples de scaling pour lesquels les microservices apportent vraiment quelque chose. Je ne parle pas de GAFAM, bien sûr.
    Mais quand on voit qu’un gros truc comme Basecamp (encore eux, oui) fait l’apologie du monolithique, franchement…

    JWT c’est très bien et avec un algo asymétrique svp.

    Encore une fois, let’s agree to disagree. Je ne vais pas recopier tout ce qui est dans le Manifeste à ce sujet.

    Oui MAIS autant de pain points déjà pris en charge par un ORM et/ou un framework même si ça ne dispense pas de les connaitre et d’y faire attention.

    Ton ORM ne répondra qu’à l’injection SQL. Ton framework ne répondra qu’au CSRF (et avec l’utilisation de jetons qui sont complètement inutiles de nos jours).

    Ça ne sert à rien d’affubler de qualificatifs péjoratifs ceux qui ne sont pas d’accord avec votre vision « intelligente et mesurée ». Les mainteneurs et tous les professionnels qui font et utilisent PHP au quotidien ont aussi une expérience qui les a conduits à penser PHP et son écosystème différemment de votre vision.

    Bah je parle de grincheux pour en avoir croisé pas mal, qui pensent que Symfony+Doctrine+APIPlatform+React/Vue est un crédo et qu’il faut brûler les hérétiques qui pensent autrement.
    Encore une fois, c’est un attitude qui n’est pas plus honorable que les personnes qui pensent que le PHP c’est de la merde.

    Je ne dis pas qu’une approche différente de la mienne n’a pas de valeur. J’ai du respect pour toutes les approches tant qu’elles sont raisonnées.
    Par contre, ce que je ne supporte pas, c’est lorsqu’une recette est appliquée sans réflexion, simplement parce que c’est la bonne pratique du moment, celle qui a le vent en poupe, celle qui est utilisée par des entreprises 30 fois plus grosses…

    Je n’ai pas du tout été convaincu mais lire une approche différente permet toujours de remettre mes convictions en question, et puis ce n’est pas tous les jours qu’on peut argumenter sur PHP. kudos.

    Merci. Alimenter la réflexion est tout ce que je cherche. On a tous des convictions, il faut juste éviter que ça devienne des certitudes − ou pire, des croyances.

  6. Après, complètement d’accord avec le fait qu le « cargo cult » devient une habitude…
    Jettez un oeil sur cela par ex: https://glasskube.dev/blog/from-java-to-go

    Je connais des tonnes de coders qui crieraient à l’infamie (surtout dans l’univers Java), et pourtant le gars avance des arguments plus que crédible (comme le manifeste) et surtout vérifiés.

  7. @stef13 Merci pour le lien, c’est intéressant.

    Ça me fait penser à un ami qui est passé au Go après de nombreuses années d’expertise dans un gros framework PHP. Il m’a dit qu’il avait retrouvé le plaisir de coder…

  8. Je peux écrire 10 pages pour justifier à quel point vous avez raison…

    Je développe depuis 25 ans et l’observation des principes simple comme ceux que vous décrivez, m’a toujours été d’un grand secours.

    Comptez ma signature sur le manifeste !

  9. Bravo Amaury pour ce super article.
    Après 20 ans de gestion du projet Dolibarr, je ne peux que confirmer qu’il est plus performant à tous les points de vue (productivité, qualité, sécurité, maintenabilité) d’appliquer ce manifeste PHP (qui est confirmé par l’expérience du terrain) que de vouloir absolument suivre des pratiques « hype », « scolaires » ou qui semble plus « pur » sur le papier mais qui sont dans la vrai vie contre productives.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Notifiez-moi des commentaires à venir via email. Vous pouvez aussi vous abonner sans commenter.