PHP 7.4, la prochaine version mineure de PHP 7, devrait être disponible le 28 novembre 2019. Il est donc temps pour nous de nous plonger dans certains des ajouts les plus excitants et de nouvelles fonctionnalités qui rendront PHP plus rapide et plus fiable.

En fait, même si PHP 7.4 améliore considérablement les performances et la lisibilité du code, PHP 8 sera le véritable jalon pour les performances de PHP, puisque la proposition pour l’inclusion du JIT a déjà été approuvée.

Quoi qu’il en soit, aujourd’hui, nous passons en revue quelques-unes des fonctionnalités les plus intéressantes et des changements que nous attendons avec PHP 7.4. Donc, avant de relire cet article, assurez-vous d’enregistrer les dates suivantes :

  • Le 6 juin : PHP 7.4 Alpha 1
  • Le 18 juillet : PHP 7.4 Beta 1 – Gel des fonctionnalités
  • Le 28 novembre : PHP 7.4 Version GA

Vous pouvez consulter la liste complète des fonctionnalités et des ajouts sur la page officielle du RFC.

Quoi de neuf dans PHP avec PHP 7.4 ?

Dans cet article, nous couvrons plusieurs changements et fonctionnalités qui devraient être ajoutés au langage avec la version finale de PHP 7.4 :

PHP 7.4 est la prochaine version mineure qui rendra PHP plus rapide et plus fiable. 🚀Lisez notre article détaillé sur les nouvelles fonctionnalités ! Cliquez pour Tweet

Oubliez array_merge : PHP 7.4 Apporte l’opérateur Spread dans l’expression de Array

Disponible depuis PHP 5.6, le unpacking d’arguments est une syntaxe pour le déballage des arrays et des Traversables en listes d’arguments. Pour décompresser un array ou un Traversable, il doit être précédé de … (3 points), comme montré dans l’exemple suivant :

function test(...$args) { var_dump($args); }
test(1, 2, 3);

Maintenant cette RFC PHP 7.4 propose d’étendre cette fonctionnalité aux définitions de array :

$arr = [...$args];

Le premier avantage déclaré de Spread Operator dans l’expression d’un array est la performance. En fait, le doc du RFC dit :

L’opérateur Spread devrait avoir de meilleures performances que array_merge. Ce n’est pas seulement parce que l’opérateur spread est une structure de langage tandis que array_merge iest une fonction, mais aussi parce que l’optimisation du temps de compilation peut être performante pour des arrays constants.

Un avantage significatif de l’opérateur Spread est qu’il supporte tous les objets traversables, alors que la fonction array_merge ne supporte que les arrays.

Voici un exemple de unpacking d’argument dans l’expression d’un array :

$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
var_dump($fruits);

Si vous exécutez ce code avec PHP 7.3 ou une version antérieure, PHP affiche une Parse Error :

Parse error: syntax error, unexpected '...' (T_ELLIPSIS), expecting ']' in /app/spread-operator.php on line 3

Au lieu de cela, PHP 7.4 retournerait un tableau :

array(5) {
	[0]=>
	string(6) "banana"
	[1]=>
	string(6) "orange"
	[2]=>
	string(5) "apple"
	[3]=>
	string(4) "pear"
	[4]=>
	string(10) "watermelon"
}

Le RFC indique que nous pouvons étendre le même tableau plusieurs fois. De plus, nous pouvons utiliser la syntaxe de l’opérateur Spread partout dans le tableau, car des éléments normaux peuvent être ajoutés avant ou après l’opérateur Spread. Le code suivant fonctionnera donc comme on peut s’y attendre :

$arr1 = [1, 2, 3];
$arr2 = [4, 5, 6];
$arr3 = [...$arr1, ...$arr2];
$arr4 = [...$arr1, ...$arr3, 7, 8, 9];

Il est également possible de décompresser les tableaux retournés par une fonction directement dans un nouveau tableau :

function buildArray(){
	return ['red', 'green', 'blue'];
}
$arr1 = [...buildArray(), 'pink', 'violet', 'yellow'];

PHP 7.4 produit le tableau suivant :

array(6) {
	[0]=>
	string(3) "red"
	[1]=>
	string(5) "green"
	[2]=>
	string(4) "blue"
	[3]=>
	string(4) "pink"
	[4]=>
	string(6) "violet"
	[5]=>
	string(6) "yellow"
}

Nous pouvons aussi utiliser la syntaxe Générator:

function generator() {
	for ($i = 3; $i <= 5; $i++) {
		yield $i;
	}
}
$arr1 = [0, 1, 2, ...generator()];

Mais nous ne sommes pas autorisés à décompresser les tableaux passés par référence. Prenons l’exemple suivant :

$arr1 = ['red', 'green', 'blue'];
$arr2 = [...&$arr1];

Si nous essayons de décompresser un tableau par référence, PHP affiche la Parse Error suivante :

Parse error: syntax error, unexpected '&' in /app/spread-operator.php on line 3

Quoi qu’il en soit, si les éléments du premier tableau sont stockés par référence, ils sont également stockés par référence dans le second tableau. En voici un exemple :

$arr0 = 'red';
$arr1 = [&$arr0, 'green', 'blue'];
$arr2 = ['white', ...$arr1, 'black'];

Et voici ce que nous obtenons avec PHP 7.4 :

array(5) {
	[0]=>
	string(5) "white"
	[1]=>
	&string(3) "red"
	[2]=>
	string(5) "green"
	[3]=>
	string(4) "blue"
	[4]=>
	string(5) "black"
}

La proposition de l’opérateur Spread a été adoptée avec 43 voix contre une.

Fonctions Arrow 2.0 (Short Closures)

En PHP, les fonctions anonymes sont considérées comme assez verbeuses et difficiles à implémenter et à maintenir. Ce RFC propose l’introduction de la syntaxe plus courte et plus claire des fonctions arrow (ou short closures), qui devrait nous permettre de nettoyer de manière significative notre code PHP.

Consider the following example:

function cube($n){
	return ($n * $n * $n);
}
$a = [1, 2, 3, 4, 5];
$b = array_map('cube', $a);
print_r($b);

PHP 7.4 permet d’utiliser une syntaxe plus concise, et la fonction ci-dessus pourrait être réécrite comme suit :

$a = [1, 2, 3, 4, 5];
$b = array_map(fn($n) => $n * $n * $n, $a);
print_r($b);

Actuellement, les, fonctions anonymes (fermetures) peuvent hériter des variables définies dans le scope parent grâce à la construction du langage use comme indiqué ci-dessous :

$factor = 10;
$calc = function($num) use($factor){
	return $num * $factor;
};

Mais avec PHP 7.4, les variables définies dans le scope parent sont implicitement capturées par valeur (liaison implicite par valeur au scope). On peut donc écrire l’ensemble de la fonction vue ci-dessus sur une seule ligne :

$factor = 10;
$calc = fn($num) => $num * $factor;

La variable définie dans le scope parent peut être utilisée dans la fonction arrow exactement comme si nous utilisions use($var), et il n’est pas possible de modifier une variable du scope parent.

La nouvelle syntaxe est une grande amélioration au langage car elle nous permet de construire un code plus lisible et maintenable. On peut aussi utiliser des use types de paramètres et de retour, des valeurs par défaut, des listes d’arguments de longueur variable (fonctions variadiques), on peut passer et retourner par référence, etc. Enfin, les fermetures courtes peuvent également être utilisées dans les méthodes de classe, et elles peuvent utiliser la variable et elles peuvent utiliser la variable $this tout comme une closure régulière.

Cette RFC a été approuvée par 51 à 8 voix, nous pouvons donc nous attendre à ce qu’elle fasse partie des ajouts PHP 7.4.

Opérateur d’assignation Coalesce Null

Ajouté avec PHP 7, l’opérateur coalesce (??) est pratique lorsque nous avons besoin d’utiliser un opérateur ternaire en conjonction avec isset(). Cela retourne le premier opérande s’il existe et n’est pas NULL. Sinon, elle retourne le deuxième opérande. En voici un exemple :

$username = $_GET['user'] ?? 'nobody';

Ce que fait ce code est assez simple : il récupère le paramètre requête et définit une valeur par défaut s’il n’existe pas. La signification de cette ligne est claire, mais que se passerait-il si nous avions des noms de variables beaucoup plus longs comme dans cet exemple du RFC ?

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

À long terme, ce code pourrait être un peu difficile à maintenir. Ainsi, dans le but d’aider les développeurs à écrire un code plus intuitif, cette RFC propose l’introduction de l’opérateur d’affectation coalesce null (??=). Ainsi, au lieu d'écrire le code précédent, nous pourrions écrire ce qui suit :

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

Si la valeur du paramètre de gauche est null, la valeur du paramètre de droite est utilisée.
Notez que, bien que l’opérateur coalesce soit un opérateur de comparaison, ??= est un opérateur d’assignation.

Cette proposition a été approuvée par 37 voix contre 4.

Propriétés Typed 2.0

Les déclarations de type d’argument, ou indices de type, permettent de spécifier le type d’une variable qui doit être transmise à une fonction ou à une méthode de classe. Les indices de type sont une fonctionnalité disponible depuis PHP 5, et depuis PHP 7.2 nous pouvons les utiliser avec le type de données object. Maintenant PHP 7.4 apporte une allusion de type un pas en avant en ajoutant le support pour les déclarations de type de propriété de première classe. En voici un exemple très simple :

class User {
	public int $id;
	public string $name;
}

Tous les types sont supportés, à l’exception de void et callable:

public int $scalarType;
protected ClassName $classType;
private ?ClassName $nullableClassType;

Le RFC explique la raison pour laquelle void et callable ne sont pas supportés :

Le type void n’est pas supporté, car il n’est pas utile et sa sémantique n’est pas claire.

Le type callable n’est pas supporté, car son comportement dépend du contexte.

Ainsi, nous pouvons utiliser en toute sécurité bool, int, float, string, array, object, iterable, self, parent, tout nom de classe ou d’interface, et les types nullables types (?type).

Les types peuvent être utilisés sur des propriétés statiques :

public static iterable $staticProp;

Ils sont également autorisés avec la notation var:

var bool $flag;

Il est possible de définir des valeurs de propriétés par défaut, qui doivent bien sûr correspondre au type de propriété déclaré, mais seules les propriétés nullables peuvent avoir une valeur null par défaut:

public string $str = "foo";
public ?string $nullableStr = null;

Le même type s’applique à toutes les propriétés d’une même déclaration :

public float $x, $y;

Que se passe-t-il si nous faisons une erreur sur le type de propriété ? Considérez le code suivant :

class User {
	public int $id;
	public string $name;
}

$user = new User;
$user->id = 10;
$user->name = [];

Dans le code ci-dessus, nous avons déclaré un type de propriété string, mais nous avons défini un tableau comme valeur de propriété. Dans un tel scénario, nous obtenons l’erreur fatale suivante :

Fatal error: Uncaught TypeError: Typed property User::$name must be string, array used in /app/types.php:9

Ce RFC a été approuvé par 70 voix contre une.

Weak References

Avec cette RFC, PHP 7.4 introduit la classe WeakReference, qui permet aux programmeurs de conserver une référence à un objet qui n’empêche pas que l’objet lui-même soit détruit.

Actuellement PHP supporte les références faibles en utilisant une extension comme pecl-weakref. Quoi qu’il en soit, la nouvelle API est différente de la classe WeakRef documentée.

Voici un exemple de l’auteur de cette proposition, Nikita Popov :

$object = new stdClass;
$weakRef = WeakReference::create($object);

var_dump($weakRef->get());
unset($object);
var_dump($weakRef->get());

Le premier var_dump imprime object(stdClass)#1 (0) {}, tandis que le second var_dump prints NULL, car l’objet référencé a été détruit.

Ce RFC est passé avec 28 à 5 votes.

Retours covariant et paramètre contravariant

La variance est une propriété des hiérarchies de classes qui décrit comment les types d’un constructeur de type affectent les sous-types. En général, un constructeur de type peut être :

  • Invariant : si le type du super-type limite le type du sous-type.
  • Covariant : si l’ordre des types est préservé (les types sont classés de plus spécifique à plus générique).
  • Contravariant : s’il inverse l’ordre (les types sont classés de plus générique à plus spécifique).

Actuellement, PHP a la plupart du temps des paramètres invariants et des types de retour, à quelques exceptions près. Cette RFC propose de permettre la covariance et la contravariance sur les types de paramètres et les types de retour, en fournissant également plusieurs exemples de code.

Voici un exemple de type de retour covariant :

interface Factory {
	function make(): object;
}

class UserFactory implements Factory {
	function make(): User;
}

Et voici un exemple de type de paramètre contravariant :

interface Concatable {
	function concat(Iterator $input); 
}
 
class Collection implements Concatable {
	// accepts all iterables, not just Iterator
	function concat(iterable $input) {/* . . . */}
}

Voir le RFC pour un examen plus approfondi de la covariance et de la contravariance en PHP 7.4.

Ce RFC a obtenu 39 voix contre une.

Preloading

Cette proposition de Dmitry Stogov est l’une de nos préférées parce qu’elle devrait apporter une augmentation significative des performances. Le preloading est le processus de chargement des bibliothèques et des frameworks dans l’OPCache à l’initialisation du module (en savoir plus sur le cycle de vie de PHP).

Cycle de vie de PHP

Cycle de vie de PHP (Source de l’image : PHP Internals)

Voici comment fonctionne le preloading dans les mots de Dmitry :

Au démarrage du serveur – avant l’exécution de tout code d’application – nous pouvons charger un certain ensemble de fichiers PHP en mémoire – et rendre leur contenu « disponible en permanence » pour toutes les requêtes ultérieures qui seront traitées par ce serveur. Toutes les fonctions et classes définies dans ces fichiers seront disponibles pour les requêtes prêtes à l’emploi, exactement comme les entités internes.

Ces fichiers sont chargés au démarrage du serveur, sont exécutés avant toute application et restent disponibles pour toute demande future. C’est formidable en termes de performances.

Le preloading est contrôlé par une directive php.ini spécifique : opcache.preload. Cette directive spécifie un script PHP à compiler et exécuter au démarrage du serveur. Ce fichier peut être utilisé pour précharger des fichiers supplémentaires, soit en les incluant, soit via la fonction opcache_compile_file() ((en savoir plus sur la documentation PHP).

Mais il y a un inconvénient. En fait, le RFC déclare explicitement :

Les fichiers préchargés restent en mémoire cache dans la mémoire opcache pour toujours. La modification de leurs fichiers sources correspondants n’aura aucun effet sans un autre redémarrage du serveur.

Cependant, toutes les fonctions définies dans les fichiers préchargés seront chargées en permanence dans les tables de fonctions et de classes PHP, et resteront disponibles pour toute requête future. Il en résultera de bonnes améliorations de la performance, même si ces améliorations peuvent être très variables.

Vous pouvez en savoir plus sur les limitations et exceptions du preloading sur la  page officielle du RFC sur le preloading.

Nouveau mécanisme de sérialisation d’objets personnalisés

C’est une autre proposition de Nikita Popov approuvée à une large majorité des voix.

Actuellement, nous avons deux mécanismes différents pour la sérialisation personnalisée d’objets en PHP :

  • Les méthodes magiques __sleep() et __wakeup()
  • L’interface Serializable

Selon Nikita, ces deux options ont des problèmes qui conduisent à un code complexe et peu fiable. Vous pouvez plonger profondément dans ce sujet dans le RFC. Ici, je mentionne simplement que le nouveau mécanisme de sérialisation devrait prévenir ces problèmes en fournissant deux nouvelles méthodes magiques, __serialize() et __unserialize(), qui combinent les deux mécanismes existants.

Cette proposition a été adoptée avec 20 contre 7 voix.

Dépréciations

Les fonctions/fonctionnalités suivantes seront obsolètes avec PHP 7.4. Pour une liste plus complète des dépréciations, consultez PHP 7.4 Upgrade Notes.

Modifier la priorité de l’opérateur de concaténation

Actuellement, en PHP, les opérateurs arithmétiques « + » et « -« , et l’opérateur de chaîne « . » sont laissés associatifs et ont la même priorité (pour en savoir plus sur la priorité de l’opérateur).

À titre d’exemple, considérons la ligne suivante :

echo "sum: " . $a + $b;

En PHP 7.3, ce code produit l’avertissement suivant :

Warning: A non-numeric value encountered in /app/types.php on line 4

Ceci parce que la concaténation est évaluée de gauche à droite. C’est la même chose que d’écrire le code suivant :

echo ("sum: " . $a) + $b;

Cette RFC propose de changer la priorité des opérateurs, en donnant à « .  » une priorité inférieure à celle des opérateurs « + » et « -« , de sorte que les additions et soustractions soient toujours effectuées avant la concaténation de chaînes. Cette ligne de code devrait être équivalente à ce qui suit :

echo "sum: " . ($a + $b);

Il s’agit d’une proposition en deux étapes :

  • A partir de la version 7.4, PHP devrait émettre un avis d’obsolescence lorsqu’il rencontre une expression non entre parenthèses avec « + », « – » et « .
  • Le changement effectif de priorité de ces opérateurs doit être ajouté avec PHP 8.

Les deux propositions ont été approuvées à une large majorité des voix.

Opérateur ternaire associatif gauche déprécié

En PHP, l’opérateur ternaire, contrairement à beaucoup d’autres langages, est associatif gauche. Selon Nikita Popof, cela peut être déroutant pour les programmeurs qui changent de langue.

Actuellement, en PHP, le code suivant est correct :

$b = $a == 1 ? 'one' : $a == 2 ? 'two' : $a == 3 ? 'three' : 'other';

C’est interprété comme ceci :

$b = (($a == 1 ? 'one' : $a == 2) ? 'two' : $a == 3) ? 'three' : 'other';

Et cela pourrait mener à des erreurs, car ce n’est peut-être pas ce que nous avons l’intention de faire. Ce RFC propose donc de déprécier et de supprimer l’utilisation de l’association de gauche pour les opérateurs ternaires et de forcer les développeurs à utiliser des parenthèses.

Il s’agit d’une autre proposition en deux étapes :

  • À partir de PHP 7.4, les ternaires imbriqués sans utilisation explicite de parenthèses lanceront un avertissement de dépréciation.
  • À partir de PHP 8.0, il y aura une erreur de compilation.

Cette proposition a été approuvée par 35 voix contre 10.

Que signifie PHP 7.4 pour les utilisateurs de WordPress ?

PHP est le langage de programmation côté serveur le plus utilisé sur le web. Selon W3Techs, en date du 28 mai 2019, l’utilisation de PHP est toujours en croissance :

PHP est utilisé par 79,0% de tous les sites web dont nous connaissons le langage de programmation côté serveur.

Utilisation de PHP (Mai 2019)

Utilisation de PHP (Mai 2019)

Malheureusement, PHP 5 est toujours utilisé par 52,4% de tous les sites web avec un langage de programmation côté serveur connu. Si vous ajoutez le nombre d’utilisateurs utilisant toujours PHP 7.0, il s’avère qu’une grande majorité des sites Web utilisent des versions non supportées de PHP.

Versions PHP supportées

Versions PHP supportées (Source de l’image : Supported Versions)

Selon la page officielle de WordPress Stats, au moment d’écrire ces lignes, 67% de tous les sites web WordPress utilisent des versions non supportées de PHP. Seulement un peu plus de 3% utilisent la dernière version : PHP 7.3. Vous pouvez voir qu’une grande majorité d’utilisateurs, plus de 31%, tournent toujours sous PHP 5.6.

Versions PHP de WordPress (mai 2019)

Versions PHP de WordPress (mai 2019)

Nous vous recommandons fortement de demander à votre hébergeur une version supportée de PHP, de préférence selon les exigences officielles de WordPress. Au moment d’écrire ces lignes, en mai 2019, WordPress exige :

  • PHP version 7.3 ou supérieure.
  • MySQL version 5.6 ou supérieure OU MariaDB version 10.1 ou supérieure.
  • Support du HTTPS

Performances de PHP 7

Les chiffres ci-dessus sont particulièrement décourageants du point de vue des performances, car PHP 7 s’est avéré beaucoup plus rapide. Voici quelques statistiques :

Nous avons exécuté nos propres tests de performance PHP avec PHP 7.3. Nous avons vu que WordPress 5.0 sur PHP 7.3 pouvait exécuter presque trois fois plus de transactions (requêtes) par seconde que PHP 5.6. Nous publierons bientôt des benchmarks pour PHP 7.4 !

Benchmarks PHP WordPress 5.0

Benchmarks PHP WordPress 5.0

  • Benchmarks avec WordPress 5.0 : 91,64 req/sec
  • Benchmarks PHP 7.0 avec WordPress 5.0: 206.71 req/sec
  • Benchmarks PHP 7.1 avec WordPress 5.0 : 210.98 req/sec
  • Benchmarks PHP 7.2 avec WordPress 5.0 : 229.18 req/sec 
  • Benchmarks PHP 7.3 avec WordPress 5.0 : 253.20 req/sec 🏆

Beaucoup sont lents à mettre à jour simplement à cause du temps nécessaire pour tester tous leurs plugins et thèmes tiers afin de s’assurer qu’ils fonctionnent correctement. Mais il arrive souvent qu’ils ne l’aient tout simplement pas encore fait.

Vérification de votre version PHP

Vous n’êtes pas sûr de la version de PHP que vous utilisez ? Une des façons les plus simples de vérifier est d’utiliser un outil comme Pingdom ou Google Chrome Devtools. Le premier en-tête de requête HTTP vous montrera généralement la version.

Vérifier la version PHP dans Pingdom

Vérifier la version PHP dans Pingdom

Ceci dépend du fait que l’hébergeur ne modifie pas la valeur de l’en-tête X-Powered-By. Cependant, beaucoup le font pour des raisons de sécurité (y compris Kinsta). Si c’est le cas, vous ne verrez peut-être pas votre version de PHP. Dans ce cas, si vous utilisez WordPress 5.2 ou une version supérieure, vous pouvez utiliser un nouvel outil Santé du site. Rendez-vous sur « Outils » → « Santé du site » → « Info » et dans la section « Serveur » vous trouverez la version PHP de votre serveur.

Vérifier la version PHP avec l'outil Santé du site de WordPress

Vérifier la version PHP avec l’outil Santé du site de WordPress

Alternativement, vous pouvez installer un plugin gratuit comme Version Info qui vous montrera quelques informations de base sur le serveur dans le pied de page de votre tableau de bord d’administration WordPress. D’autres façons de voir votre version PHP incluent le téléchargement d’un fichier via FTP, ou simplement en contactant votre hébergeur et en lui demandant.

Mise à jour vers PHP 7.4

La version finale de PHP 7.4 n’est pas encore arrivée. Cependant, vous pouvez tester votre site WordPress localement ou vérifier vos scripts dans un environnement comme Docker, qui vous permet de tester différentes versions de PHP depuis la ligne de commande.

Une fois que PHP 7.4 sera disponible, vous pourrez utiliser un environnement de staging chez Kinsta, car il ressemblera davantage à un site de production en direct. Créez un environnement de développement en quelques clics dans le tableau de bord MyKinsta.

Environnement de développement WordPress

Environnement de développement WordPress

Il vous suffit de changer le moteur PHP du site de développement sous « Outils » et vous pouvez commencer à tester pour vous assurer de la compatibilité de vos plugins et thèmes tiers.

Changement vers PHP 7.3

Changement vers PHP 7.3

Nous ajouterons le support pour PHP 7.4 dès qu’il sera officiellement disponible et testé par nos développeurs. En attendant, vous pouvez faire vos propres tests avec PHP 7.4 sur votre ordinateur en utilisant un outil comme Docker.

Installation et exécution de PHP 7.4 sur Docker

Heureusement, vous n’avez pas besoin de compiler et configurer PHP 7.4 manuellement. Si Docker est déjà installé sur votre système, il vous suffit d’installer l’image non officielle de Docker PHP-FPM 7.4 et d’exécuter vos tests depuis la ligne de commande en quelques secondes.

Installation de l'image Nginx de docker

Installation de l’image Nginx de docker

Si vous préférez exécuter votre code PHP 7.4 dans votre navigateur, vous devez également installer une image Nginx ou Apache. Mais ne vous inquiétez pas. Il suffit de suivre les instructions du développeur. Copiez et collez les commandes de la page Docker Image dans votre outil de ligne de commande, et vous êtes prêt à vous lancer.

Résumé

Dans cet article, nous avons couvert un bon nombre de changements et d’ajouts auxquels nous pouvons nous attendre avec la sortie de PHP 7.4. Si vous recherchez la liste complète des fonctionnalités, ainsi que la documentation RFC officielle, consultez les ressources suivantes :

Nous vous tiendrons au courant des dernières informations concernant PHP 7.4 et sa sortie.

Êtes-vous prêt à tester les prochaines fonctionnalités de PHP ? Laquelle est votre préférée ? Faites-nous part de vos idées dans les commentaires ci-dessous.

115
Partages