Adoptez le PHP d'aujourd'hui : types stricts, fonctions fléchées, opérateur nullsafe, enums et expression match.
Ouvrir cette leçon dans KodokonPHP moderne assume le typage. declare(strict_types=1), placé en première instruction du fichier, désactive les conversions implicites : passer la chaîne '10' à un paramètre float lève une TypeError au lieu d'être converti en silence. Typez paramètres et valeurs de retour : vos erreurs éclatent tôt, au bon endroit, plutôt que trois fichiers plus loin.
<?php
declare(strict_types=1);
function applyDiscount(
float $price,
float $rate = 0.1
): float {
return round($price * (1 - $rate), 2);
}
echo applyDiscount(49.99);
echo PHP_EOL;
echo applyDiscount(100.0, 0.25);Les fonctions fléchées fn condensent les fonctions anonymes d'une seule expression. Grand avantage sur les closures classiques : elles capturent automatiquement les variables du contexte parent, sans clause use. Elles brillent avec array_map() et array_filter().
<?php
declare(strict_types=1);
$prices = [12.5, 49.9, 8.0, 120.0];
$rate = 0.2;
$discounted = array_map(
fn (float $p): float => round($p * (1 - $rate), 2),
$prices
);
$affordable = array_filter(
$discounted,
fn (float $p): bool => $p < 50
);
print_r($affordable);L'opérateur nullsafe ?-> court-circuite un appel dès qu'un maillon de la chaîne vaut null, au lieu de provoquer une erreur fatale. Combiné à ??, il remplace des pyramides de if par une seule ligne lisible.
<?php
declare(strict_types=1);
class Address
{
public function __construct(
public readonly string $city
) {
}
}
class User
{
public function __construct(
public readonly ?Address $address = null
) {
}
}
$alice = new User(new Address('Lyon'));
$bob = new User();
echo $alice->address?->city ?? 'Ville inconnue';
echo PHP_EOL;
echo $bob->address?->city ?? 'Ville inconnue';Les enums donnent un vrai type aux ensembles fermés de valeurs (statuts, rôles) : impossible de créer un statut inexistant. Et match remplace avantageusement switch : comparaison stricte, résultat renvoyé comme valeur, et une UnhandledMatchError si aucun cas ne correspond - un garde-fou contre les oublis.
<?php
declare(strict_types=1);
enum OrderStatus: string
{
case Pending = 'pending';
case Shipped = 'shipped';
case Delivered = 'delivered';
public function label(): string
{
return match ($this) {
self::Pending => 'En attente',
self::Shipped => 'Expédiée',
self::Delivered => 'Livrée',
};
}
}
$status = OrderStatus::from('shipped');
echo $status->label();