New self vs new static in PHP: Was wählen im Jahr 2025?
Stellen Sie sich vor: Sie programmieren seit mehreren Jahren in PHP, fühlen sich sicher, und plötzlich stellt Ihr Kollege (oder Stack Overflow) die Frage: «Warum wird in meiner Kindklasse ein Objekt der Elternklasse erstellt, obwohl ich den Konstruktor mit new self() aufrufe?». Kommt Ihnen das bekannt vor? Wenn ja, sind Sie nicht allein. Das Thema new self vs new static ist eine der beliebtesten Fragen auf Stack Overflow mit tausenden Aufrufen. Und im Jahr 2025, mit der Veröffentlichung neuer PHP-Versionen, ist das Verständnis dieses Unterschieds noch wichtiger geworden.
In diesem Artikel werden wir analysieren, wie sich self und static bei der Objekterstellung unterscheiden, wie das Late Static Binding funktioniert und vor allem, wann was verwendet werden sollte. Los geht's!
Das Problem: self zeigt immer auf die Elternklasse
Beginnen wir mit einem klassischen Beispiel. Angenommen, wir haben eine Elternklasse BaseController und eine Kindklasse ApiController.
<?php
class BaseController { public static function create() { return new self(); // Achtung! self ist BaseController }}
class ApiController extends BaseController { // Erbt create()}
$api = ApiController::create();var_dump($api); // object(BaseController)#1 (0) { }?>Wir erwarteten ein Objekt von ApiController, erhielten aber BaseController. Warum? Weil self im Kontext der Elternklasse immer auf die Klasse verweist, in der es geschrieben wurde, nicht auf die Klasse, über die es aufgerufen wurde. Dies ist das frühe statische Binden. PHP «merkt» sich die Klasse während der Kompilierung, nicht während der Ausführung.
Lösung: Verwenden Sie static
Um die Situation zu beheben, müssen Sie self durch static ersetzen. Dies aktiviert den Mechanismus des Late Static Binding (LSB).
<?php
class BaseController { public static function create() { return new static(); // static ist die Klasse, die die Methode aufgerufen hat }}
class ApiController extends BaseController { // Erbt create()}
$api = ApiController::create();var_dump($api); // object(ApiController)#1 (0) { }?>Jetzt ist $api ein Objekt von ApiController. static wird zur Laufzeit aufgelöst und zeigt auf die Klasse, über die die Methode aufgerufen wurde. Dies ist das Late Static Binding.
Wann self und wann static verwenden?
Im Jahr 2025 trennen die Best Practices diese beiden Ansätze klar. Hier sind die grundlegenden Regeln.
Verwenden Sie self, wenn:
- Sie innerhalb einer einzelnen Klasse arbeiten und keine Vererbung für diese Methode erwarten.
- Sie ein Objekt genau der Klasse erstellen müssen, in der der Code geschrieben ist, nicht einer Kindklasse.
- Sie auf Konstanten oder statische Eigenschaften zugreifen, die nicht überschrieben werden sollen.
Beispiel: Eine Factory-Methode, die garantiert ein Objekt der Basisklasse zurückgibt.
<?php
class Logger { protected static $instance;
public static function getInstance() { if (self::$instance === null) { self::$instance = new self(); // Immer Logger } return self::$instance; }}?>Verwenden Sie static, wenn:
- Sie Code für die Erweiterung entwerfen – zum Beispiel abstrakte Klassen oder Traits.
- Sie möchten, dass Kindklassen ihre eigenen Instanzen erstellen können.
- Sie das Factory Method- oder Builder-Entwurfsmuster verwenden.
Beispiel: Eine abstrakte Klasse für Entitäten.
<?php
abstract class Entity { public static function create(array $data): static {\