Constructor Property Promotion ist eine der elegantesten Spracherweiterungen in PHP 8.0, die dazu beiträgt, den Boilerplate-Code in Klassen erheblich zu reduzieren. Diese Funktion vereinfacht die Deklaration von Klasseneigenschaften, die über den Konstruktor initialisiert werden – ein Muster, das in objektorientiertem PHP-Code sehr häufig vorkommt.
Vor PHP 8.0 erforderte die Deklaration einer Klasse mit Eigenschaften, die im Konstruktor initialisiert werden, viel redundanten Code:
class Benutzer {
private string $name;
private string $email;
private ?int $alter;
public function __construct(string $name, string $email, ?int $alter = null) {
$this->name = $name;
$this->email = $email;
$this->alter = $alter;
}
// Getter und Setter...
}Diese Implementierung enthält dreifache Wiederholung: die Eigenschaftsdeklaration, die Parameterdeklaration im Konstruktor und die Zuweisungen innerhalb des Konstruktors.
Mit Constructor Property Promotion können wir die Eigenschaftsdeklaration und die Zuweisung direkt in die Parameterliste des Konstruktors integrieren:
class Benutzer {
public function __construct(
private string $name,
private string $email,
private ?int $alter = null
) {
// Der Konstruktor kann leer sein oder zusätzliche Initialisierungslogik enthalten
}
// Getter und Setter...
}Dieses kompaktere Syntax führt zu deutlich weniger Code, bleibt dabei aber ebenso ausdrucksstark und typsicher.
Wenn Sie ein Sichtbarkeitsmodifikator (public,
protected, private oder seit PHP 8.2 auch
readonly) vor einem Konstruktorparameter angeben, geschieht
Folgendes:
Constructor Property Promotion lässt sich gut mit anderen PHP-Features kombinieren:
class Produkt {
public function __construct(
private string $name,
private float $preis,
private ?string $beschreibung = null
) {}
}class ImmutableConfig {
public function __construct(
private readonly string $apiKey,
private readonly string $apiUrl,
private readonly int $timeout = 30
) {}
}class Zahlungsmethode {
public function __construct(
private string $name,
private string|int $identifier,
private bool $isActive = true
) {}
}Bei der Verwendung von Constructor Property Promotion gibt es einige Besonderheiten zu beachten:
class Newsletter {
private array $abonnenten = [];
public function __construct(
private string $name,
private string $absender,
array $initialAbonnenten = []
) {
// $initialAbonnenten wird nicht als Eigenschaft erstellt
$this->abonnenten = $initialAbonnenten;
}
}class Artikel {
private array $kommentare = [];
private DateTime $erstelltAm;
public function __construct(
private string $titel,
private string $inhalt,
private string $autor
) {
$this->erstelltAm = new DateTime();
}
}...) als Promoted Properties
verwenden:// Dies funktioniert NICHT:
public function __construct(private string ...$tags) {}class Bestellung {
public function __construct(
private string $id,
private array $positionen = [],
private ?DateTime $datum = null
) {
$this->datum = $datum ?? new DateTime();
}
}Constructor Property Promotion ist besonders nützlich in folgenden Szenarien:
class BenutzerDTO {
public function __construct(
public readonly int $id,
public readonly string $name,
public readonly string $email
) {}
}class BenutzerService {
public function __construct(
private BenutzerRepository $repository,
private LoggerInterface $logger,
private EventDispatcherInterface $eventDispatcher
) {}
}class AppConfig {
public function __construct(
private readonly string $appName,
private readonly string $version,
private readonly array $supportedLocales,
private readonly bool $debugMode = false
) {}
}Um die Codequalität weiter zu verbessern, können Sie Docblocks mit Constructor Property Promotion kombinieren:
class Zahlungsvorgang {
public function __construct(
/** Die eindeutige Transaktions-ID */
private string $transaktionsId,
/** Der zu zahlende Betrag in Cent */
private int $betrag,
/** Das verwendete Zahlungsmittel */
private string $zahlungsmethode,
/** Zeitpunkt der Zahlung */
private ?DateTime $zeitpunkt = null
) {
$this->zeitpunkt ??= new DateTime();
}
}