PHP 8: Toutes les nouveautés  38 min  

PHP 8: Toutes les informations

PHP 8 sortira le 26 novembre 2020. Il s’agit d’une nouvelle version majeure, ce qui signifie qu’il va introduire quelques changements de rupture, ainsi que beaucoup de nouvelles fonctionnalités et des améliorations des performances. PHP 8 est en développement très actif en ce moment, avec son premier alpha prévu le 18 Juin 2020.

En raison des changements de rupture, il ya une plus grande chance que vous aurez besoin d’apporter quelques modifications dans votre code pour le faire fonctionner sur PHP 8. Si vous avez été à jour avec les dernières versions cependant, la mise à niveau ne devrait pas être trop difficile, puisque la plupart des modifications de rupture ont été déconseillés avant dans les versions 7.* . Et ne vous inquiétez pas, toutes ces dépréciations sont répertoriées dans ce post.

En plus de briser les changements, PHP 8 apporte également un bel ensemble de nouvelles fonctionnalités telles que le compilateur JITtypes d’unionattributs, et plus encore.


Nouvelles fonctionnalités

En commençant par les nouvelles fonctionnalités, n'oubliez pas que le PHP 8 est toujours en cours de développement actif, donc cette liste s'allongera avec le temps.

 

Types d’union rfc

Compte tenu de la nature dactylographyée dynamiquement de PHP, il ya beaucoup de cas où les types d’union peuvent être utiles. Les types d’union sont une collection de deux types ou plus qui indiquent que l’un ou l’autre de ces types peut être utilisé.

public function foo(Foo|Bar $input): int|float;

Notez que ne peut jamais faire partie d’un type d’union, car il indique « aucune valeur de retour du tout ». En outre, les syndicats peuvent être écrits à l’aide, ou en utilisant la notation existante:voidnullable|null?

public function foo(Foo|null $foo): void;
public function bar(?Bar $bar): void;

Jit rfc

Le compilateur jit — juste à temps — promet d’importantes améliorations du rendement, mais pas toujours dans le contexte des demandes web. Il n’y a pas eu de repères précis à ce stade, mais ils viendront certainement.

Si vous voulez en savoir plus sur ce que le JIT peut faire pour PHP, vous pouvez lire un autre post que j’ai écrit à ce sujet ici.


L’opérateur nullsafe rfc

Si vous connaissez l’opérateur de fusion null, vous connaissez déjà ses lacunes : il ne fonctionne pas sur les appels de méthode. Au lieu de cela, vous avez besoin de contrôles intermédiaires, ou compter sur les aides fournies par certains cadres:optional

$startDate = $dateAsString = $booking->getStartDate();
$dateAsString = $startDate ? $startDate->asDateTimeString() : null;

Avec l’ajout de l’opérateur nullsafe, nous pouvons maintenant avoir null coalescing-comme le comportement sur les méthodes!

$dateAsString = $booking->getStartDate()?->asDateTimeString();

Arguments nommés rfc

Les arguments nommés vous permettent de transmettre des valeurs à une fonction, en spécifiant le nom de la valeur, de sorte que vous n’avez pas à prendre leur commande en considération, et vous pouvez également ignorer les paramètres facultatifs!

function foo(string $a, string $b, ?string $c = null, ?string $d = null) {
   /* … */ 
}
 foo(
    b: 'value b',
    a: 'value a',
    d: 'value d',
 );

Vous pouvez lire à leur sujet en profondeur dans ce post.


Attributs rfc

Attributs, communément appelés annotations dans d’autres langues, offre un moyen d’ajouter des méta-données aux classes, sans avoir à analyser les docblocks.

En ce qui concerne un coup d’oeil rapide, voici un exemple de ce que les attributs ressemblent, à partir de la RFC:

use App\Attributes\ExampleAttribute;

@@ExampleAttribute
class Foo
{
    @@ExampleAttribute
    public const FOO = 'foo';
 
    @@ExampleAttribute
    public $x;
 
    @@ExampleAttribute
    public function foo(@@ExampleAttribute $bar) { }
}
@@Attribute
class ExampleAttribute
{
    public $value;
 
    public function __construct($value)
    {
        $this->value = $value;
    }
}

Note that this base used to be called in the original RFC, but was changed with another RFC afterwards. If you want to take a deep dive in how attributes work, and how you can build your own; you can read about attributes in depth on this blog.AttributePhpAttribute


Match expression rfc

You could call it the big brother of the expresion: can return values, doesn't require statements, can combine conditions, uses strict type comparisons and doesn't do any type coercion.switch match break

It looks like this:

$result = match($input) {
    0 => "hello",
    '1', '2', '3' => "world",
};

Vous pouvez lire sur l’expression du match en détail, ici.


Promotion de propriétés constructeur rfc

Ce RFC ajoute du sucre syntaxique pour créer des objets de valeur ou des objets de transfert de données. Au lieu de spécifier les propriétés de classe et un constructeur pour eux, PHP peut maintenant les combiner en un seul.

Au lieu de faire ceci :

class Money 
{
    public Currency $currency;
 
    public int $amount;
 
    public function __construct(
        Currency $currency,
        int $amount,
    ) {
        $this->currency = $currency;
        $this->amount = $amount;
    }
}

Vous pouvez maintenant le faire :

class Money 
{
    public function __construct(
        public Currency $currency,
        public int $amount,
    ) {}
}

Il ya beaucoup plus à dire sur la promotion de la propriété, vous pouvez lire à leur sujet dans ce post dédié.


Nouveau type de retour static rfc

Alors qu’il était déjà possible de revenir , n’était pas un type de retour valide jusqu’à PHP 8. Compte tenu de la nature dactylographamente dynamique de PHP, c’est une fonctionnalité qui sera utile à de nombreux développeurs.selfstatic

class Foo
{
    public function test(): static
    {
        return new static();
    }
}

Nouveau type mixed rfc

Certains pourraient l’appeler un mal nécessaire: le type provoque beaucoup d’avoir des sentiments mitigés. Il ya un très bon argument à faire pour elle si: un type manquant peut signifier beaucoup de choses en PHP:mixed

  • Une fonction renvoie rien ou null
  • Nous nous attendons à l’un des nombreux types
  • Nous nous attendons à un type qui ne peut pas être le type laissé entendre dans PHP

En raison des raisons ci-dessus, c’est une bonne chose que le type est ajouté. signifie lui-même l’un des types suivants :mixedmixed

  • array
  • bool
  • callable
  • int
  • float
  • null
  • object
  • resource
  • string

Notez que peut également être utilisé comme un paramètre ou un type de propriété, pas seulement comme un type de retour.mixed

Notez également que depuis déjà comprend , il n’est pas autorisé à le rendre nullable. Ce qui suit déclenchera une erreur :mixednull

// Fatal error: Mixed types cannot be nullable, null is already part of the mixed type.
function bar(): ?mixed {}

Lancer l’expression rfc

Ce RFC passe d’une déclaration à une expression, ce qui permet de faire exception dans de nombreux nouveaux endroits :throw

$triggerError = fn () => throw new MyError();

$foo = $bar['offset'] ?? throw new OffsetDoesNotExist('offset');

Héritage avec des méthodes privées rfc

Auparavant, PHP appliquait les mêmes contrôles d’héritage sur les méthodes publiques, protégées et privées. En d’autres termes: les méthodes privées doivent suivre les mêmes règles de signature de méthode que les méthodes protégées et publiques. Cela n’a pas de sens, puisque les méthodes privées ne seront pas accessibles par les classes d’enfants.

Ce RFC a modifié ce comportement, de sorte que ces contrôles d’héritage ne sont plus effectués sur des méthodes privées. En outre, l’utilisation de n’a pas non plus de sens, donc cela va maintenant déclencher un avertissement:final private function

Warning: Private methods cannot be final as they are never overridden by other classes

Cartes faibles rfc

Construit sur le faiblerefs RFC qui a été ajouté dans PHP 7.4, une implémentation est ajoutée dans PHP 8. contient des références à des objets, qui n’empêchent pas ces objets d’être collectés.WeakMapWeakMap

Prenons l’exemple des ORM, ils implémentent souvent des caches qui contiennent des références à des classes d’entités pour améliorer les performances des relations entre entités. Ces objets d’entité ne peuvent pas être collectés, tant que ce cache a une référence à eux, même si le cache est la seule chose qui les référence.

Si cette couche de mise en cache utilise des références faibles et des cartes à la place, PHP va ordures recueillir ces objets quand rien d’autre ne les fait référence plus. En particulier dans le cas des ORM, qui peuvent gérer plusieurs centaines, voire des milliers d’entités dans le cadre d’une demande; cartes faibles peuvent offrir une meilleure façon, plus favorable aux ressources de traiter avec ces objets.

Voici à quoi ressemblent les cartes faibles, un exemple du RFC :

class Foo 
{
    private WeakMap $cache;
 
    public function getSomethingWithCaching(object $obj): object
    {
        return $this->cache[$obj]
           ??= $this->computeSomethingExpensive($obj);
    }
}

Autoriser les objets ::class rfc

Une petite nouveauté utile : il est désormais possible d'utiliser sur des objets, au lieu de devoir utiliser sur eux. Elle fonctionne de la même manière que  .::classget_class()get_class()

$foo = new Foo();

var_dump($foo::class);

Non-capturing catches rfc

Chaque fois que vous vouliez saisir une exception avant PHP 8, vous deviez la stocker dans une variable, que vous utilisiez cette variable ou non. Avec les captures non saisies, vous pouvez omettre la variable, donc à la place de celle-ci :

try {
    // Something goes wrong
} catch (MySpecialException $exception) {
    Log::error("Something went wrong");
}

Vous pouvez faire ceci:

try {
    // Something goes wrong
} catch (MySpecialException) {
    Log::error("Something went wrong");
}

Note that it's required to always specify the type, you're not allowed to have an empty . If you want to catch all exceptions and errors, you can use as the catching type.catchThrowable


Virgule de fin dans les listes de paramètres rfc

Déjà possible lors de l’appel d’une fonction, la prise en charge de virgule s’ensayait encore dans les listes de paramètres. Il est maintenant autorisé dans PHP 8, ce qui signifie que vous pouvez faire ce qui suit:

public function(
    string $parameterA,
    int $parameterB,
    Foo $objectfoo,
) {
    // …
}

Créer des objets à partir de l’interface DateTime

Vous pouvez déjà créer un objet à partir d’un objet à l’aide , mais l’inverse était délicat. En ajoutant et il ya maintenant une façon généralisée de convertir et les objets les uns aux autres.DateTimeDateTimeImmutable DateTime::createFromImmutable($immutableDateTime) DateTime::createFromInterface() DatetimeImmutable::createFromInterface() DateTime DateTimeImmutable

DateTime::createFromInterface(DateTimeInterface $other);

DateTimeImmutable::createFromInterface(DateTimeInterface $other);

Nouvelle interface Stringable rfc

L’interface peut être utilisée pour taper un indice tout ce qui est une chaîne ou des implémentations . En outre, chaque fois qu’une classe implémente , il implémente automatiquement l’interface dans les coulisses et il n’est pas nécessaire de l’implémenter manuellement.Stringable__toString()__toString()

class Foo
{
    public function __toString(): string
    {
        return 'foo';
    }
}

function bar(Stringable $stringable) { /* … */ }

bar(new Foo());
bar('abc');

Nouvelle fonction str_contains() rfc

Certains pourraient dis-le est attendu depuis longtemps, mais nous n’avons finalement pas à compter sur plus de savoir si une chaîne contient une autre chaîne.strpos()

Au lieu de faire ceci :

if (strpos('string with lots of words', 'words') !== false) { /* … */ }

Vous pouvez maintenant le faire

if (str_contains('string with lots of words', 'words')) { /* … */ }

Nouveau et fonctions str_starts_with()str_ends_with() rfc

Deux autres depuis longtemps, ces deux fonctions sont maintenant ajoutées dans le noyau.

str_starts_with('haystack', 'hay'); // true
str_ends_with('haystack', 'stack'); // true

Nouvelle fonction fdiv() pr

La nouvelle fonction fait quelque chose de similaire à la et les fonctions, ce qui permet la division par 0. Au lieu d’erreurs que vous obtiendrez, ou , selon le cas.fdiv()fmod()intdiv()INF-INFNAN


Nouvelle fonction get_debug_type() rfc

get_debug_type() renvoie le type d’une variable. On dirait que quelque chose ferait? renvoie une sortie plus utile pour les tableaux, les chaînes, les classes anonymes et les objets.gettype()get_debug_type()

Par exemple, appeler une classe reviendrait . L’utilisation renvoie le nom de classe.gettype()\Foo\Barobjectget_debug_type()

Une liste complète des différences entre et peut être trouvée dans le RFC.get_debug_type()gettype()


Nouvelle fonction get_resource_id() pr

Les ressources sont des variables spéciales dans PHP, se référant à des ressources externes. Un exemple est une connexion MySQL, une autre poignée de fichier.

Chacune de ces ressources se voit attribuer un ID, bien qu’auparavant la seule façon de savoir que l’id était de lancer la ressource à :int

$resourceId = (int) $resource;

PHP 8 ajoute les fonctions, ce qui rend cette opération plus évidente et plus sûre de type :get_resource_id()

$resourceId = get_resource_id($resource);

Méthodes abstraites dans l’amélioration des traits rfc

Les traits peuvent spécifier des méthodes abstraites qui doivent être implémentées par les classes qui les utilisent. Il ya une mise en garde cependant: avant PHP 8 la signature de ces implémentations de méthode n’ont pas été validées. Ce qui suit était valide :

trait Test {
    abstract public function test(int $input): int;
}

class UsesTrait
{
    use Test;

    public function test($input)
    {
        return $input;
    }
}

PHP 8 effectuera la validation appropriée de la signature de la méthode lors de l’utilisation d’un trait et de la mise en œuvre de ses méthodes abstraites. Cela signifie que vous aurez besoin d’écrire ceci à la place:

class UsesTrait
{
    use Test;

    public function test(int $input): int
    {
        return $input;
    }
}

Implémentation d’objet de token_get_all() rfc

La fonction renvoie un tableau de valeurs. Ce RFC ajoute une classe avec une méthode. Cette implémentation fonctionne avec des objets au lieu de valeurs simples. Il consomme moins de mémoire et est plus facile à lire.token_get_all()PhpTokenPhpToken::getAll()


Modifications de syntaxe variables rfc

Du RFC : « La syntaxe variable uniforme RFC a résolu un certain nombre d’incohérences dans la syntaxe variable de PHP. Ce RFC a l’intention de traiter une petite poignée de cas qui ont été négligés.


Taper des annotations pour les fonctions internes externes

Beaucoup de gens ont lancé pour ajouter des annotations de type approprié à toutes les fonctions internes. C’était un problème de longue date, et enfin soluble avec tous les changements apportés à PHP dans les versions précédentes. Cela signifie que les fonctions et les méthodes internes auront des informations de type complet dans la réflexion.


ext-json toujours disponible rfc

Auparavant, il était possible de compiler PHP sans l’extension JSON activée, ce n’est plus possible. Depuis JSON est si largement utilisé, il est préférable que les développeurs peuvent toujours compter sur elle étant là, au lieu d’avoir à s’assurer que l’extension existent en premier.

Rupture des changements

Comme mentionné précédemment: il s’agit d’une mise à jour majeure et donc il y aura des changements de rupture. La meilleure chose à faire est de jeter un oeil à la liste complète des changements de rupture sur le document de mise à niveau.

Beaucoup de ces changements de rupture ont été dépréciés dans les versions précédentes 7.* si, donc si vous avez été rester à jour au fil des ans, il ne devrait pas être si difficile à mettre à niveau vers PHP 8.


Erreurs de type cohérentes rfc

Les fonctions définies par l’utilisateur dans PHP seront déjà jeter , mais les fonctions internes n’ont pas, ils ont plutôt émis des avertissements et retourné . Depuis PHP 8, le comportement des fonctions internes est cohérent.TypeErrornull


Avertissements de moteur reclassifiés rfc

Beaucoup d’erreurs qui précédemment seulement déclenché des avertissements ou des avis, ont été convertis en erreurs appropriées. Les avertissements suivants ont été modifiés.

  • Variable non définie : exception au lieu d’un avisError
  • Index de tableau non défini : avertissement au lieu d’un avis
  • Division par zéro : exception au lieu d’avertissementDivisionByZeroError
  • Tentative d’incrément/décrément de la propriété '%s’de non-objet : exception au lieu d’avertissementError
  • Tentative de modification de la propriété '%s’de non-objet : exception au lieu d’avertissementError
  • Tentative d’attribution de propriétés '%s’de non-objet : exception au lieu d’avertissementError
  • Création d’un objet par défaut à partir d’une valeur vide : exception au lieu d’avertirError
  • Essayer d’obtenir des biens '%s’de non-objet: avertissement au lieu de préavis
  • Propriété non définie : %s::$%s : avertissement au lieu d’un avis
  • Impossible d’ajouter un élément au tableau lorsque l’élément suivant est déjà occupé : exception au lieu d’avertirError
  • Impossible de décoster dans une variable non-tableau : exception au lieu d’avertissementError
  • Impossible d’utiliser une valeur scalaire comme tableau : exception au lieu d’avertirError
  • Seuls les tableaux et peuvent être déballés : exception au lieu d’avertissementTraversablesTypeError
  • Argument non valide fourni pour l’avant-garde(): exception au lieu d’avertissementTypeError
  • Type de compensation illégal : exception au lieu d’avertissementTypeError
  • Type de décalage illégal dans isset ou vide : exception au lieu d’avertissementTypeError
  • Type de décalage illégal dans unset : exception au lieu d’avertissementTypeError
  • Conversion de tableau à la chaîne : avertissement au lieu d’avis
  • ID de ressource#%d utilisé comme décalage, coulée à entier (%d) : avertissement au lieu d’un avis
  • Le casting de décalage de chaîne s’est produit : avertissement au lieu de l’avis
  • Décalage de chaîne nonnitialisé : %d : avertissement au lieu de préavis
  • Impossible d’attribuer une chaîne vide à un décalage de chaîne : exception au lieu d’avertissementError
  • La ressource fournie n’est pas une ressource de flux valide : exception au lieu d’avertissementTypeError

L’opérateur @ ne fait plus taire les erreurs fatales

Il est possible que ce changement puisse révéler des erreurs qui ont de nouveau été cachées avant PHP 8. Assurez-vous de définir sur vos serveurs de production!display_errors=Off


Niveau de déclaration d’erreur par défaut

C’est maintenant au lieu de tout, mais et . Cela signifie que de nombreuses erreurs peuvent apparaître qui ont été précédemment silencieusement ignoré, bien que probablement déjà existant avant PHP 8.E_ALLE_NOTICEE_DEPRECATED


Mode d’erreur DOP par défaut rfc

À partir du RFC : le mode d’erreur par défaut actuel pour PDO est silencieux. Cela signifie que lorsqu’une erreur SQL se produit, aucune erreur ou avertissement ne peut être émis et aucune exception n’est levée à moins que le développeur n’implémente sa propre gestion explicite des erreurs.

Ce RFC modifie l’erreur par défaut dans PHP 8.PDO::ERRMODE_EXCEPTION


Préséance de concaténation rfc

Bien que déjà déprécié dans PHP 7.4, ce changement est maintenant entré en vigueur. Si vous écrivez quelque chose comme ceci:

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

PHP l’interpréterait auparavant comme ceci :

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

PHP 8 le fera de sorte qu’il est interprété comme ceci:

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

Contrôles de type plus stricts pour les opérateurs arithmétiques et bitwise rfc

Avant PHP 8, il était possible d’appliquer des opérateurs arithmétiques ou bitwise sur des tableaux, des ressources ou des objets. Ce n’est plus possible, et lancera un TypeError:

[] % [42];
$object + 4;

Modifications de la signature de la méthode de réflexion

Trois signatures de méthodes de classes de réflexion ont été modifiées :

ReflectionClass::newInstance($args);
ReflectionFunction::invoke($args);
ReflectionMethod::invoke($object, $args);

Sont maintenant devenus:

ReflectionClass::newInstance(...$args);
ReflectionFunction::invoke(...$args);
ReflectionMethod::invoke($object, ...$args);

Le guide de mise à niveau spécifie que si vous étendez ces classes et que vous souhaitez toujours prendre en charge PHP 7 et PHP 8, les signatures suivantes sont autorisées :

ReflectionClass::newInstance($arg = null, ...$args);
ReflectionFunction::invoke($arg = null, ...$args);
ReflectionMethod::invoke($object, $arg = null, ...$args);

Tri stable rfc

Avant PHP 8, les algorithmes de tri étaient instables. Cela signifie que l’ordre des éléments égaux n’était pas garanti. PHP 8 modifie le comportement de toutes les fonctions de tri en tri stable.


Erreur fatale pour les signatures de méthode incompatibles rfc

Du RFC : erreurs d’héritage dues à des signatures de méthode incompatibles, lancez actuellement une erreur fatale ou un avertissement en fonction de la cause de l’erreur et de la hiérarchie de l’héritage.


Autres dépréciations et changements

Au cours du développement PHP 7.*, plusieurs dépréciations ont été ajoutées qui sont maintenant finalisées dans PHP 8.

Source: https://stitcher.io/blog/new-in-php-8

Auteur

KilioZ

Étudiant en BTS Travaux Publics au Pas-de-Calais. Fondateur du réseau social Dev-Time, développeur web depuis 2013.


  Discord : Matéo M.#6452   Reddit : KilioZDev