PHP 7.4

55
29
nov.
2019
PHP

Il y a bien longtemps qu’une nouvelle version de PHP n’avait pas été commentée ici. En fait, depuis la sortie de la version 7.0 qui s’est faite dans la douleur après l’abandon de la version 6. Le langage sort désormais avec une nouvelle version chaque fin d’année. La rétrocompatibilité est un point qui n’est pas négligé d’une version à l’autre, d’où une évolution plutôt lente.
La majorité des logiciels peut migrer sans trop d’appréhension. Depuis plusieurs versions, l’amélioration des performances est un point essentiel du fait de la concurrence avec HHVM, développé par Facebook. Au final, cette version, qui est la dernière de la branche 7, apporte un système de type plus fort, plus de performance et fait en sorte de diminuer le code cérémonial, aka boilerplate.

Sommaire

La version PHP 7.4 apporte de nombreuses fonctionnalités et en supprime une :

Réduction de la verbosité du langage

Null coalescing assignment operator

Cette nouveauté évite de dupliquer le nom de la variable de part et d’autre de l’opérateur d’affectation. Par exemple, les deux lignes suivantes ont le même comportement :

$this->request->data['comments']['user_id'] = $this->request->data['comments']['user_id'] ?? 'value';

$this->request->data['comments']['user_id'] ??= 'value';

Fonctions fléchées

Cette nouveauté a été définie dans cette RFC. Elle vise, entre autres, à rendre l’usage du côté fonctionnel du langage plus agréable. Oui, oui, PHP a quelques marges d’amélioration à ce niveau‑là !

Ici, il sera plus agréable de remplacer les bons vieux foreach() pour traiter les tableaux par des array_map() ou des array_filter(). Globalement ça s’inspire des fonctions fléchées du JavaScript.

$double = array_map(fn($e) => 2 * $e, [1, 2, 3]);

$utilisateursMineurs = array_filter($users, fn(User $user) => $user->age < 18);

Nous pouvons noter la cohérence du langage entre les deux fonctionnalités, l’ordre d’appel entre le tableau et la méthode de retour n’est pas le même.

Évolution de la syntaxe

Séparateur d’unité

Il est possible d’ajouter un séparateur d’unité pour les nombres afin de les rendre plus lisibles. Par exemple, $milliard = 1000000000 pourra s’écrire $milliard = 1_000_000_000. En revanche, attention à l’utilisation, il y a des risques de ne pas affecter la bonne valeur.

Les opérateurs ternaires imbriqués ne sont plus associés par la gauche

PHP était un des rares langages à proposer une associativité des ternaires par la gauche. Et pour éviter aux développeurs de se prendre les pieds dans le tapis, elle disparaît. Le mieux étant tout de même d’éviter les ternaires imbriqués.

Un typage plus présent

Depuis la version 7.0, le typage est de plus en plus présent au sein du langage. Il est possible de typer les arguments et le type de retour d’une méthode. Dorénavant, il sera aussi possible de spécifier le type des attributs d’une classe.

class Sportif
{
    private Sport $sport = 'cyclimse';
    private Humain $humain;

    public function __construct(Humain $humain, Sport $sport)
    {
        $this->humain = $humain;
        $this->sport = $sport;
    }

    public function entrainer():void
    {
        $this->humain->ajouteEntrainement($this->sport);
    }

Ces ajouts sur les types facilitent la compréhension du code. En revanche, sans contrainte, PHP a un typage dynamique, donc le code suivant n’a pas forcément un résultat intuitif :

$somme = function (int $a, int $b): int {return $a + $b; };
echo $somme("1", 2.1); // affiche 3

En forçant une évaluation stricte des types en plaçant declare(strict_types=1); en début de fichier, le code déclenche une erreur sur le typage. Ainsi, le développeur est forcé à prêter plus attention aux arguments passés aux méthodes.

En PHP 8, s’ajouteront les types unions, et espérons qu’ils seront accompagnés par des énumérations.

Améliorations des performances

Comme à chaque fois depuis la version 7.0, les performances natives du langage s’améliorent. Il est actuellement un des langages interprétés les plus rapides. Il faut néanmoins relativiser, car un langage qui va vite c’est une chose, mais si du temps est perdu à attendre le retour d’une requête en base de données ou, pire, depuis le réseau, les gains côté PHP ne sont pas très utiles. C’est d’ailleurs une des raisons pour lesquelles le JIT ne sera pas activé par défaut en PHP 8.

Foreign Function Interface

L’idée est ici de pouvoir appeler un programme en C depuis un script PHP, un peu à l’idée de ce qu’il est possible de faire en Python en écrivant du CPython.

Il sera possible d’écrire des choses du genre (source) :

$libc = FFI::cdef("
    int printf(const char *format, ...);
    const char * getenv(const char *);
    unsigned int time(unsigned int *);

    typedef unsigned int time_t;
    typedef unsigned int suseconds_t;

    struct timeval {
        time_t      tv_sec;
        suseconds_t tv_usec;
    };

    struct timezone {
        int tz_minuteswest;
        int tz_dsttime;
    };

    int gettimeofday(struct timeval *tv, struct timezone *tz);
", "libc.so.6");

$libc->printf("Hello World from %s!\n", "PHP");
var_dump($libc->getenv("PATH"));
var_dump($libc->time(null));

$tv = $libc->new("struct timeval");
$tz = $libc->new("struct timezone");
$libc->gettimeofday(FFI::addr($tv), FFI::addr($tz));
var_dump($tv->tv_sec, $tv->tv_usec, $tz);

Cette fonctionnalité ouvre la possibilité d’effectuer des traitements qui habituellement ne se font pas en PHP. D’ailleurs, voici un exemple d’utilisation.

Préchargement

L’idée est de charger des fichiers afin que PHP crée un « binaire ». En contre‑partie, la mise à jour du binaire devra attendre un prochain démarrage et le temps de démarrage sera un peu plus long. Ce préchargement est donc intéressant pour les fichiers qui évoluent rarement, globalement ceux du cadriciel. En fonction des projets, il peut être intéressant de ne précharger que les fichiers les plus utilisés, comme le montre ce commentaire.

La suite ?

P++, Bringing Peace to the Galaxy

En août 2019, la communauté s’était posé la question sur la création d’une variante du PHP : P++ (c’est un nom temporaire et on peut aussi lire PHP++). L’idée était de nettoyer le langage de ses aspects pas toujours cohérents, mais conservés pour des raisons de compatibilité. Un peu comme pour le langage Raku créé initialement pour rendre le langage Perl plus accessible. Le moteur d’exécution de PHP pourrait alors interpréter indifféremment un PHP Classic <?php ?> et un P++ <?p++ ?>. Benjamin Eberlei propose d’utiliser <?php declare(std=20); ?>.

Un sondage ouvert à tous montre que 60 % des répondants souhaitent un PHP 8 rétrocompatible, et un petit 20 % pour passer à P++. Les mainteneurs se sont aussi exprimés lors d’un sondage plus formel, et P++ ne verra pas le jour, car trop d’énergie à investir sur deux langages, la fragmentation de la communauté PHP…

PHP 8

En fin d’année prochaine, PHP 8 devrait débarquer avec quelques gros changements. Le plus important est, peut‑être, la compilation à la volée (JIT) proposée par Dmitry Stogov.

En 2011, Facebook annonçait des performances incroyables avec HHVM, son implémentation d’un moteur d’exécution PHP exploitant la compilation à la volée. Mais cette technique pour optimiser l’exécution de PHP n’avait pas été retenue pour le moteur d’exécution de référence. Néanmoins, PHP 7 a pu bénéficier d’autres mécanismes pour améliorer ses performances, rattraper HHVM et susciter un regain d’intérêt pour PHP.

Aujourd’hui, près de dix ans plus tard, il ne reste plus beaucoup d’options pour continuer d’améliorer les performances de PHP. Bien que la compilation à la volée ne devrait pas beaucoup améliorer la performance du rendu des pages Web, cette technique apporte deux avantages :

  • une très bonne approche pour l’utilisation de PHP dans du calcul intensif, et cela devrait permettre d’utiliser PHP dans des domaines où on ne le considérait pas comme une option ;
  • permettre de basculer des pans entiers du code PHP par l’équivalent dans un langage plus proche du processeur (comme le langage C) lors de cette compilation à la volée.

Cette compilation à la volée a failli être intégrée dans PHP 7.4 en mode expérimental. Ce changement correspond au plus grand commit de l’histoire de PHP.

La future version PHP 8 apportera également d’autres améliorations que nous aurons plaisir à partager dans un an…

2029

Utilisera‐t‐on PHP dans dix ans, en 2029 ?

D’après le site W3Techs, PHP est encore et toujours le langage le plus utilisé côté serveur Web. Les statistiques sont mises à jour quotidiennement. Voici les chiffres lors de la rédaction de cette dépêche :

  • 79 % PHP ;
  • 11 % ASP.NET ;
  •   5 % Java et Scala ;
  •   3 % Ruby (vive LinuxFr.org) ;
  •   2 % HTML (fichiers statiques) ;
  •   1 % Python ;
  •   1 % JavaScript.

Pour la méthodologie utilisée, lire les explications fournies par W3Techs.

Avec un zoom sur les versions de PHP :

  • PHP 3    0,0x %   😱 plus maintenu depuis 19 ans !
  • PHP 4    0,5 %   😵 plus maintenu depuis 11 ans !
  • PHP 5  58 %   😮 plus maintenu depuis un an ;
  • PHP 6    0 %   🤐 version abandonnée, jamais sortie ;
  • PHP 7  42 %   😀 version actuelle ;
  • PHP 8    0 %   🤩 sortie prévue dans un an.

Aller plus loin

  • # Plus d’informations sur les Foreign Function Interface (FFI)

    Posté par  . Évalué à 5.

    Un article assez détaillé sur le potentiel de cette nouvelle fonctionnalité :

    https://jolicode.com/blog/php-7-4-et-ffi-ce-quil-faut-retenir

  • # Phôte de phrape

    Posté par  . Évalué à 5.

    Attention ! Il y a une petite faute à cyclimse dans le code de démo…
    Ou alors c'est que j'ai pas assez regardé le flim

    Plus sérieusement il y a (je pense) une faute dans ce code :

    $somme = function (int $a, int $b): int {return $a + $b; };
    echo $s("1", 2.1); // affiche 3

    Si le echo se fait sur $s et pas sur $somme, c'est sûr qu'on va avoir du mal à comprendre le résultat !

    --

    Mis à part ça, merci beaucoup pour ce résumé, de très bonnes choses pour PHP qui m'intéresse vraiment beaucoup de nouveau sur les dernières versions, après une v5 qui m'avait un peu dégoûté du langage.

    Dommage qu'il y ait encore beaucoup d'incohérences au niveau des noms des fonctions et de l'ordre des paramètres, c'est un héritage nécessaire pour la rétro compatibilité, mais lourd à porter.

    • [^] # Re: Phôte de phrape

      Posté par  . Évalué à 3. Dernière modification le 29 novembre 2019 à 11:32.

      Il y a bien une erreur dans le code. La bonne version est :

      $somme = function (int $a, int $b): int {return $a + $b; };
      echo $somme("1", 2.1); // affiche 3

      Plus qu’à attendre le passage d’une personne de l’équipe de modération pour corriger la dépêche.

    • [^] # Re: Phôte de phrape

      Posté par  (site web personnel) . Évalué à 1.

      Dommage qu'il y ait encore beaucoup d'incohérences au niveau des noms des fonctions et de l'ordre des paramètres, c'est un héritage nécessaire pour la rétro compatibilité, mais lourd à porter.

      En vrai avec un bon IDE ça se passe très très bien.
      Un petit coup de Psalm par dessus et ça se passe encore mieux

      • [^] # Re: Phôte de phrape

        Posté par  . Évalué à 6.

        En vrai, avec un langage bien construit, t'as même pas besoin d'avoir un bon IDE pour ne pas te prendre la tête ;)

        • [^] # Re: Phôte de phrape

          Posté par  (site web personnel) . Évalué à 4.

          Bien sûr, je ne dis pas le contraire.

          L'inconsistance de la librairie standard est tjrs relevée comme étant une grosse tare du langage, bien souvent par ceux qui ne pratiquent pas au quotidien (aucune idée de si c'est le cas ici). Je me permettais de signaler qu'avec un outilage adéquat, ce problème est quasi inexistant.

          C'est d'autant plus intéressant que la réécriture de la lib std PHP n'interviendra heureusement jamais "juste" pour reordonner des paramètres.

          Tout langage a ses défauts (et peut être même que PHP en a plus que les autres), là où ça devient plus intéressant c'est ce que l'écosystème met en place autour de ces défauts pour les gommer. Et justement, l'écosystème PHP depuis ces 5 à 7 dernières années est particulièrement bien foutu et bien fournit.

          Après c'est vrai que ça fait bien de basher PHP.

          • [^] # Re: Phôte de phrape

            Posté par  . Évalué à 7.

            J'ai programmé dans assez de langages depuis 25 ans pour ne pas avoir besoin de "basher" quoi que ce soit (à part les premières versions de swift, parce que là Apple était vraiment en roue libre :D).

            Mais je ne pense pas que c'est en inventant un écosystème servant à oublier les erreurs du langage que les choses progressent. Parfois il faut casser pour reconstruire par dessus.

            Une petite réécriture de la lib pour remettre à plat les fondamentaux (avec un layer de compatibilité pas trop compliqué à maintenir) serait quand même intéressant.
            Vu les nouveautés que le langage apporte depuis la version 7, ce ne serait pas un mal.

          • [^] # Re: Phôte de phrape

            Posté par  . Évalué à 7.

            Une lib standard ça vie est il est tout à fait possible de créer de nouveaux pans pour remplacer d'anciens bouts sans pour autant les supprimer. C'est par exemple ce qui est fait en java

            https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

  • # 79% des sites en PHP...

    Posté par  . Évalué à 2.

    …c'est surtout dû au fait que la majorité des sites web dans le monde fonctionne sur WordPress. Une grosse part étant constituée de sites institutionnels, pas sûr que WP+PHP soit vraiment nécessaire. On allègerait beaucoup de servers à se servir de ce couple comme environnement de "dev" de sites, puis générer et publier des pages statiques. IMHO

    • [^] # Re: 79% des sites en PHP...

      Posté par  . Évalué à 10.

      Je pense que tu exagères la proportion de Wordpress. D'après https://www.whoishostingthis.com/compare/wordpress/stats/ :
      Wordpress aurait entre 51 et 58% des CMS et 34% de tous les sites. Ouais ça fait un tiers du Web, c'est énorme, mais ça ne suffit pas à expliquer les 79% de PHP (même en rajoutant Joomla/Drupal &co). Sinon tous les daycideurs te diront qu'ils veulent pouvoir publier des news sur leur site institutionnel (même si ils ne le font qu'une fois par an en pratique) et ils ne voudront pas devoir passer par qqun pour regénérer les pages statiques.
      "On allègerait beaucoup de servers" mais pour l'agence de com basique, quoi de plus simple que vendre une install Wordpress + Thème, remplir textes & photos puis fournir les clés au client ? Ça juste marche. Jusqu'à la prochaine faille du plugin de Carousel…

  • # cache cache !

    Posté par  . Évalué à 5.

    Il faut néanmoins relativiser, car un langage qui va vite c’est une chose, mais si du temps est perdu à attendre le retour d’une requête en base de données

    C'est aussi mon constat : on pense pas assez à cacher les requêtes en BDD, qui sont un sacré consommateur de ressources!

    ⚓ À g'Auch TOUTE! http://afdgauch.online.fr

    • [^] # Re: cache cache !

      Posté par  . Évalué à 5.

      C'est la base pour moi de cacher les requêtes SQL. Je les mets dans des fichiers au fin fond du filesystem, pour que personne ne les trouvent !!

  • # Travail sur SQLite

    Posté par  (site web personnel, Mastodon) . Évalué à 10.

    Pour info, j'ai encore pas mal bossé cette année à améliorer le support SQLite dans PHP, et la version 7.4 inclue :

    • support de l'ouverture de bases SQLite en lecture seule dans PDO (read only)
    • support de la notation @parametre dans les requêtes dans SQLite3, comme paramètre nommé (en plus de :parametre)
    • ajout de la méthode SQLite3Stmt::getSQL qui renvoie le contenu de la requête SQL préparée (éventuellement avec les paramètres remplacés dans la requête si la version de SQLite le supporte), pratique pour débuguer ! Doc : https://www.php.net/manual/fr/sqlite3stmt.getsql.php
    • ajout de la méthode SQLite3::backup (doc à venir) qui permet de faire une sauvegarde d'une base de données à chaud pendant qu'on l'utilise

    Pour PHP 8 (ou prochaine release de PHP 7.4 ?) j'ai un patch en cours pour le support de l'API d'autorisation (authorizer) dans SQLite3 qui permet d'autoriser ou non certains types de requêtes (par exemple n'autoriser que les SELECT) ou à certaines données (possibilité de filtrer à quelles tables et colonnes on a accès), super pratique !

    Toutes ces fonctionnalités sont développées pour les besoins de Garradin le gestionnaire d'association :)

    « Je vois bien à quels excès peut conduire une démocratie d'opinion débridée, je le vis tous les jours. » (Nicolas Sarkozy)

    • [^] # Re: Travail sur SQLite

      Posté par  . Évalué à 4.

      Pour PHP 8 (ou prochaine release de PHP 7.4 ?) j'ai un patch en cours pour le support de l'API d'autorisation (authorizer) dans SQLite3 qui permet d'autoriser ou non certains types de requêtes (par exemple n'autoriser que les SELECT) ou à certaines données (possibilité de filtrer à quelles tables et colonnes on a accès), super pratique !

      C'est pas la commande GRANT qui est censée faire ça ?

  • # Python ?

    Posté par  . Évalué à 3.

    Python 1.3%. Alors la je suis déçu. Je trouve django tellement bien, tellement simple et cohérent. J'adore. Quand je vois les bouts de code en php j'échangerai jamais 1 baril de django contre 2 baril de symphony ou même de RoR.

    • [^] # Re: Python ?

      Posté par  . Évalué à 1.

      Prendre Symphony comme exemple de framework PHP, ce n'est pas vraiment lui rendre hommage (sauf depuis la v4, éventuellement). Bref, je pense qu'on peut comparer Django (que j'apprécie beaucoup) avec quelque chose de plus ressemblant.

    • [^] # Re: Python ?

      Posté par  (site web personnel) . Évalué à 2.

      Tout pareil. Django est surtout hyper efficace pour faire des petites applis où la beauté de l'interface n'est pas super importante, avec toutes les possibilités de personnalisation de l'interface d'administration (petit à petit, ce qui permet d'avoir une version minimale fonctionnelle rapidement).

  • # C'est bien

    Posté par  . Évalué à 2.

    Je ne fais plus de PHP, et je n'ai jamais vraiment apprécié le langage. Mais ayant été un gros utilisateur de PHP (surtout PHP7) pour le boulot, je suis quand même content de voir que le projet avance bien, et dans le bon sens.

    Je pense que je serai amené à refaire du PHP un de ces jours (peut-être que ça sera du PHP8, qui sait ?), et je sais déjà que je ne partirai pas avec un si mauvais a priori.

  • # Rétrocompatibilité?

    Posté par  . Évalué à 2.

    La rétrocompatibilité est un point qui n’est pas négligé d’une version à l’autre, d’où une évolution plutôt lente.

    Suivi de

    Les opérateurs ternaires imbriqués ne sont plus associés par la gauche

    Du coup, est-ce qu’il ne viennent pas de casser la rétrocompatibilité sur une numéro de version mineur ? :/

    Séparateur d’unité
    […]
    En revanche, attention à l’utilisation, il y a des risques de ne pas affecter la bonne valeur.

    Hum, c’est à dire ?

  • # C'est même très bien:

    Posté par  . Évalué à 2. Dernière modification le 27 décembre 2019 à 20:27.

    Je suis bloqué depuis 2017 à gérer, a faire évoluer des sites sous php5.6
    Quand ils ont supprimé les fonctions mysql_*, obligé d'installer un ppa pour les vieux sites sans pdo.

    Je trouve les fonctions fléchées sympa, mais à part sur un array_filter(), j'irais pas remplacer mon foreach().

    Le $zaza ??= $toto c'est très cool.

    Embarquer du C, génial. Moi ce que j'attends c'est la compilation à la volée, avec du C embarqué ça ne doit être pas mal du tout pour optimiser des fonctions. Mais le C, ils le mettent en cache ou ils recompilent à chaques fois?

    Laravel est déjà sous 7.4 :)

    • [^] # Re: C'est même très bien:

      Posté par  . Évalué à 2.

      Le JIT est encore à l'état de nourrisson, j'ai comme l'impression qu'il ne sera prêt pas avant quelques temps. Si tu regardes la vidéo en lien, tu verras qu'un équivalent en php de gd est bien plus lent.
      Le préchargement me semble plus intéressant et accessible. Avec un peu de tuning et la maintenance de quelques fichiers les performances sont significativement améliorées.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.