Classes en lecture seule, une nouvelle extension « Random », et plus encore
Dans cet article je vais vous expliquer rapidement les nouveaux goodies que PHP nous offre pour Noël avec le Version PHP 8.2.
Il s’agit d’une mise à jour majeure du langage PHP. Il contient de nombreuses nouvelles fonctionnalités, notamment des classes en lecture seule, null, false et true en tant que types autonomes, des propriétés dynamiques obsolètes, des améliorations de performances, etc.
PHP < 8.2
class BlogData
{
public readonly string $title;public readonly Status $status;
public function __construct(string $title, Status $status)
{
$this->title = $title;
$this->status = $status;
}
}
PHP ≥ 8.2
readonly class BlogData
{
public string $title;public Status $status;
public function __construct(string $title, Status $status)
{
$this->title = $title;
$this->status = $status;
}
}
Depuis PHP 8.2.0, une classe peut être marquée avec le readonly
modificateur. Marquer une classe comme readonly
ajoutera le modificateur en lecture seule à chaque propriété déclarée et empêcher la création de propriétés dynamiques.
De plus, il est impossible de leur ajouter un support en utilisant le AllowDynamicPropertiesAllowDynamicProperties attribut. Tenter de le faire déclenchera une erreur de compilation.
#[AllowDynamicProperties]
readonly class Foo {
}// Fatal error: Cannot apply #[AllowDynamicProperties] to readonly class Foo
Comme ni les propriétés non typées, ni les propriétés statiques ne peuvent être marquées avec le readonly
modificateur, readonly
les classes ne peuvent pas non plus les déclarer.
readonly class Foo
{
public $bar;
}// Fatal error: Readonly property Foo::$bar must have type
?>
readonly class Foo
{
public static int $bar;
}// Fatal error: Readonly class Foo cannot declare static properties
Rappelez-vous qu’un readonly
peut être étendue si, et seulement si, la classe enfant est aussi une readonly
classer.
PHP < 8.2
class Foo {
public function bar(mixed $entity) {
if ((($entity instanceof A) && ($entity instanceof B)) || ($entity === null)) {
return $entity;
}throw new Exception('Invalid entity');
}
}
PHP ≥ 8.2
class Foo {
public function bar((A&B)|null $entity) {
return $entity;
}
}
DNF (psss, si vous voulez en savoir plus sur la forme normale disjonctive voir cette page Wikipédia) les types nous permettent de combiner syndicat et intersection types, suivant une règle stricte : lors de la combinaison de types d’union et d’intersection, les types d’intersection doivent être regroupés avec des crochets.
Voir quelques exemples ci-dessous pour le comprendre un peu plus
// Accepts an object that implements both A and B,
// OR an object that implements D.
(A&B)|D// Accepts an object that implements C,
// OR a child of X that also implements D,
// OR null.
C|(X&D)|null
// Accepts an object that implements all three of A, B, and D,
// OR an int,
// OR null.
(A&B&D)|int|null
PHP < 8.2
class Falsy
{
public function almostFalse(): bool { /* ... */ *}public function almostTrue(): bool { /* ... */ *}
public function almostNull(): string|null { /* ... */ *}
}
PHP ≥ 8.2
class Falsy
{
public function alwaysFalse(): false { /* ... */ *}public function alwaysTrue(): true { /* ... */ *}
public function alwaysNull(): null { /* ... */ *}
}
Voir un exemple de la raison pour laquelle la définition de la true
le type a du sens en effet
class User {
function isAdmin(): bool
}class Admin extends User
{
function isAdmin(): true
{
return true;
}
}
PHP ≥ 8.2
use Random\Engine\Xoshiro256StarStar;
use Random\Randomizer;$blueprintRng = new Xoshiro256StarStar(
hash('sha256', "Example seed that is converted to a 256 Bit string via SHA-256", true)
);
$fibers = [];
for ($i = 0; $i < 8; $i++) {
$fiberRng = clone $blueprintRng;
// Xoshiro256**'s 'jump()' method moves the blueprint ahead 2**128 steps, as if calling
// 'generate()' 2**128 times, giving the Fiber 2**128 unique values without needing to reseed.
$blueprintRng->jump();
$fibers[] = new Fiber(function () use ($fiberRng, $i): void {
$randomizer = new Randomizer($fiberRng);
echo "{$i}: " . $randomizer->getInt(0, 100), PHP_EOL;
});
}
// The randomizer will use a CSPRNG by default.
$randomizer = new Randomizer();
// Even though the fibers execute in a random order, they will print the same value
// each time, because each has its own unique instance of the RNG.
$fibers = $randomizer->shuffleArray($fibers);
foreach ($fibers as $fiber) {
$fiber->start();
}
L’extension « random » fournit une nouvelle API orientée objet pour la génération de nombres aléatoires. Au lieu de s’appuyer sur un générateur de nombres aléatoires (RNG) à l’échelle mondiale utilisant le Mersenne Twister algorithm l’API orientée objet fournit plusieurs classes (« Engine ») donnant accès à des algorithmes modernes qui stockent leur état dans des objets pour permettre plusieurs séquences ensemençables indépendantes.
La \Random\Randomizer
La classe fournit une interface de haut niveau pour utiliser le caractère aléatoire du moteur pour générer un entier aléatoire, mélanger un tableau ou une chaîne, sélectionner des clés de tableau aléatoires, etc.
PHP ≥ 8.2
trait Foo
{
public const CONSTANT = 1;
}class Bar
{
use Foo;
}
var_dump(Bar::CONSTANT); // 1
var_dump(Foo::CONSTANT); // Error
Les constantes de trait peuvent être définies de la même manière que les constantes de classe et sont aplaties dans la définition de la classe de composition de la même manière que les définitions de propriété et de méthode dans les traits.
Vous ne pouvez pas accéder à la constante via le nom du trait, mais vous pouvez accéder à la constante via la classe qui utilise le trait.
PHP < 8.2
class User
{
public $name;
}$user = new User();
$user->last_name = 'Doe';
$user = new stdClass();
$user->last_name = 'Doe';
PHP ≥ 8.2
class User
{
public $name;
}$user = new User();
$user->last_name = 'Doe'; // Deprecated notice
$user = new stdClass();
$user->last_name = 'Doe'; // Still allowed
La création de propriétés dynamiques est obsolète pour éviter les erreurs et les fautes de frappe, à moins que la classe ne l’accepte en utilisant le #[\AllowDynamicProperties]
attribut. stdClass
permet des propriétés dynamiques.
Utilisation de la __get
/__set
Les méthodes magiques ne sont pas affectées par ce changement.
La suppression de la prise en charge des propriétés dynamiques constitue une rupture de compatibilité descendante importante. Alors que le code PHP moderne déclare systématiquement les propriétés utilisées, ce n’est pas nécessairement le cas pour le code hérité.
Lorsque vous rencontrez un avertissement d’obsolescence de propriété dynamique, vous pouvez faire un certain nombre de choses pour l’éviter. Le plus simple et le plus courant serait d’ajouter simplement la déclaration de propriété :
class Test {
public $value; // <-- Add property declaration.public function __construct($value) {
$this->value = $value;
}
}
Alors qu’est-ce que tu attends? Consultez le guide de migration pour passer à PHP 8.2 et essayez-le ! J’espère que cet article vous a plu et à bientôt pour le prochain !