On ne fait pas de la magie

«Toute technologie suffisamment avancée est indiscernable de la magie.» Arthur C. Clarke

Évolution des extensions WordPress

Dans le cadre des prestations de maintenance que j’assure sur des sites WordPress, je suis parfois confronté à des besoins d’évolution des thèmes et des extensions pour fonctionner avec PHP 8 et les nouvelles versions de WordPress.

Cet article présente les problèmes courants et les solutions que l’on peut appliquer pour les résoudre.

Principaux problèmes avec PHP 8

L’utilisation de PHP 8 sur des extensions anciennes provoque souvent des erreurs, liées à des fonctionnalités dépréciées ou disparues. Les principales concernent le constructeur d’une classe défini avec le nom de la classe, l’utilisation de create_function et l’encapsulation  de plusieurs ’opérateurs ternaires sans parenthèses.

Constructeur de classe avec nom de la classe

Depuis PHP 8, le constructeur d’une classe est la fonction __construct, sans indication d’erreur alors qu’en PHP 7, le constructeur pouvait être une fonction ayant le nom de la classe.

Le code suivant affiche la valeur 42 en PHP 7.4 et n’affiche rien en PHP 8.

class demo {
  function demo() {
    $this->x=42;
  }
}
$d = new demo();
echo $d->x;

Exécuter l’exemple

La difficulté pour trouver ces constructions est qu’aucune erreur n’est signalée par PHP 8. Il faut relever les avertissements émis en PHP 7.4 : Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP;ou utiliser une recherche avec grep pour repérer ces classes, par exemple :

egrep -l -i -z 'class[[:space:]]+([a-zA-Z_][a-zA-Z0-9_]*)[^}]*function[[:space:]]+\1[[:space:]]*\(' *.php

Fonction create function

Jusqu’à PHP 8, il existait une fonction create_function permettant de créer dynamiquement des fonctions à partir d’une chaine de caractères. On pouvait trouver du code comme celui ci :

add_filter('login_errors',create_function('$a', "return null;"));

Depuis PHP 8, il faut modifier ces instructions et on peut utiliser une fonction anonyme, pour obtenir cela :

add_filter('login_errors',function($a) {return null;});

Exécuter l’exemple

Enchainement d’opérateur ternaire sans parenthèses

Il est tout à fait possible d’imbriquer des opérateurs ternaires, mais depuis PHP 8 il faut ajouter des parenthèses pour délimiter l’opérateur interne. Ainsi ce code fonctionne en PHP 7.4 et provoque une erreur en PHP 8 :

$https = empty($_SERVER["HTTPS"]) ? '' : ($_SERVER["HTTPS"] == "on") ? "s" : "";

La syntaxe en PHP 8, qui peut aussi être employée en PHP 7.4 et permet d’éviter un avertissement, est :

$https = empty($_SERVER["HTTPS"]) ? '' : (($_SERVER["HTTPS"] == "on") ? "s" : "");

Exécuter l’exemple

Utilisation des accolades pour accéder aux éléments de tableau

Il est possible, en PHP 7.4, d’utiliser des accolades pour accéder à un champ de tableau, comme ceci : echo $table{0};

Cette syntaxe n’est plus admise par PHP 8 et doit être remplacée par echo $table[0];

Exécuter l’exemple

Noms de fonction en conflit

Un autre catégorie d’erreur rencontrée est le conflit de nom entre une fonction définie dans l’extension et une fonction apparue dans une nouvelle version de WordPress. Par exemple, si l’extension définit une fonction get_options(), la mise à jour de WordPress après la version 6.4 échoue, car cette fonction y apparaît. La solution est alors de changer le nom de la fonction dans l’extension, partout où ce nom est utilisé.

Évolution des extensions WordPress : une tâche simple

Comme vous pouvez le constater, faire évoluer une extension WordPress pour l’adapter aux évolutions des versions de PHP et de WordPress est une opération relativement simple. C’est une bonne nouvelle, car cela évite de rester bloquer sur des anciennes versions, souvent moins performantes et présentant des risques de sécurité, ou d’avoir à chercher et mettre en place une extension équivalente, voire de changer de thème…

Commentaires

Laisser un commentaire

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