Einfache Klassendefinitionen beginnen mit dem Schlüsselwort class, gefolgt von einem Klassennamen, gefolgt von einem Paar geschweifter Klammern, die die Definitionen der Eigenschaften und Methoden der Klasse enthalten.
Der Klassenname kann jeder gültige Bezeichner sein, vorausgesetzt es ist kein von PHP
reserviertes Wort. Ein gültiger
Klassenname beginnt mit einem Buchstaben oder einem Unterstrich, gefolgt
von einer beliebigen Anzahl von Buchstaben, Ziffern oder Unterstrichen;
als regulärer Ausdruck formuliert:
^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$
.
Eine Klasse darf aus ihren eigenen Konstanten, Variablen ("Eigenschaften" genannt) und Funktionen ("Methoden" genannt) bestehen.
Beispiel #1 Definition einer einfachen Klasse
<?php
class SimpleClass
{
// Deklaration einer Eigenschaft
public $var = 'ein Standardwert';
// Deklaration einer Methode
public function displayVar() {
echo $this->var;
}
}
?>
Die Pseudovariable $this ist verfügbar, falls eine Methode aus einem Objektkontext heraus aufgerufen wird. $this ist eine Referenz auf das aufrufende Objekt (üblicherweise das Objekt, zu dem die Methode gehört, aber möglicherweise ein anderes Objekt, falls die Methode statisch aus dem Kontext eines zusätzlichen Objektes aufgerufen wird). Von PHP 7.0.0 an führt das statische Aufrufen nicht-statischer Methoden aus einem inkompatiblen Kontext dazu, dass $this innerhalb der Methode nicht definiert ist. Der statische Aufruf einer nicht-statischen Methode aus einem inkompatiblen Kontext wurde von PHP 5.6.0 an missbilligt. Von PHP 7.0.0 an ist der statische Aufruf einer nicht-statischen Methode allgemein missbilligt (auch wenn sie aus einem kompatiblen Kontext aufgerufen wird). Vor PHP 5.6.0 lösten solche Aufrufe bereits eine Strict-Notice aus.
Beispiel #2 Einige Beispiele für die $this-Pseudovariable
Wir nehmen an, dass error_reporting für dieses Beispiel deaktiviert ist; andernfalls würde der folgende Code Deprecated- bzw. Strict-Notices auslösen, je nach verwendeter PHP-Version.
<?php
class A
{
function foo()
{
if (isset($this)) {
echo '$this ist definiert (';
echo get_class($this);
echo ")\n";
} else {
echo "\$this ist nicht definiert.\n";
}
}
}
class B
{
function bar()
{
A::foo();
}
}
$a = new A();
$a->foo();
A::foo();
$b = new B();
$b->bar();
B::bar();
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe mit PHP 5:
$this ist definiert (A) $this ist nicht definiert. $this ist definiert (B) $this ist nicht definiert.
Das oben gezeigte Beispiel erzeugt folgende Ausgabe mit PHP 7:
$this ist defined (A) $this ist nicht defined. $this ist nicht defined. $this ist nicht defined.
Um eine Instanz einer Klasse zu erzeugen, muss das new-Schlüsselwort verwendet werden. Ein Objekt wird immer erzeugt, außer wenn das Objekt einen definierten Konstruktor besitzt, der aufgrund eines Fehlers eine Exception wirft. Klassen sollten vor ihrer Instantiierung definiert werden (in manchen Fällen ist dies eine Notwendigkeit).
Wenn ein string mit dem Namen einer Klasse mit new genutzt wird, wird eine neue Instanz dieser Klasse erzeugt. Falls sich die Klasse in einem Namensraum befindet, muss der vollqualifizierte Name hierfür genutzt werden.
Hinweis:
Falls der Konstruktor keine Übergabeargumente erwartet, können die Klammern hinter dem Klassennamen weggelassen werden.
Beispiel #3 Eine Instanz erzeugen
<?php
$instanz = new SimpleClass();
// dies ist auch mit einer Variablen möglich:
$klassenname = 'SimpleClass';
$instanz = new $klassenname(); // new SimpleClass()
?>
Im Kontext einer Klasse ist es möglich, neue Objekte mit new self und new parent anzulegen.
Wenn man eine bereits erzeugte Instanz einer Klasse einer neuen Variablen zuweist, wird die neue Variable auf die selbe Instanz zugreifen wie das Objekt, das zugewiesen wurde. Dieses Verhalten ist das selbe, wenn man Instanzen an Funktionen übergibt. Eine Kopie eines bereits erzeugten Objektes erhält man, indem man es klont.
Beispiel #4 Objektzuweisung
<?php
$instanz = new SimpleClass();
$zugewiesen = $instanz;
$referenz =& $instanz;
$instanz->var = '$zugewiesen wird diesen Wert haben';
$instanz = null; // $instanz und $referenz werden null
var_dump($instanz);
var_dump($referenz);
var_dump($zugewiesen);
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
NULL NULL object(SimpleClass)#1 (1) { ["var"]=> string(30) "$zugewiesen wird diesen Wert haben" }
Mit PHP 5.3.0 wurden neue Möglichkeiten zur Erzeugung von Instanzen eines Objekts eingeführt:
Beispiel #5 Erzeugen neuer Objekte
<?php
class Test
{
static public function getNew()
{
return new static;
}
}
class Child extends Test
{}
$obj1 = new Test();
$obj2 = new $obj1;
var_dump($obj1 !== $obj2);
$obj3 = Test::getNew();
var_dump($obj3 instanceof Test);
$obj4 = Child::getNew();
var_dump($obj4 instanceof Child);
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
bool(true) bool(true) bool(true)
PHP 5.4.0 führte die Möglichkeit ein, auf ein Mitglied eines neu erzeugten Objekts in einem einzigen Ausdruck zuzugreifen:
Beispiel #6 Zugriff auf ein Mitglied eines neu erzeugten Objekts
<?php
echo (new DateTime())->format('Y');
?>
Das oben gezeigte Beispiel erzeugt eine ähnliche Ausgabe wie:
2016
Klassen-Eigenschaften und -Methoden leben in separaten "Namensräumen", so dass es eine Eigenschaft und eine Methode des selben Namens geben kann. Der Zugriff auf eine Eigenschaft und eine Methode wird gleich notiert, und ob auf eine Eigenschaft zugegriffen oder eine Methode aufgerufen wird, hängt einzig und allein vom Kontext ab, d.h. ob die Verwendung ein Variablenzugriff oder ein Funktionsaufruf ist.
Beispiel #7 Variablenzugriff vs. Methodenaufruf
<?php
class Foo
{
public $bar = 'Eigenschaft';
public function bar() {
return 'Methode';
}
}
$obj = new Foo();
echo $obj->bar, PHP_EOL, $obj->bar(), PHP_EOL;
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
Eigenschaft Methode
Das bedeutet, dass der Aufruf einer anonymen Funktion, die einer Eigenschaft zugewiesen wurde, nicht direkt möglich ist. Statt dessen muss beispielsweise die Eigenschaft zunächst einer Variablen zugewiesen werden. Von PHP 7.0.0 an ist es möglich, eine solche Eigenschaft direkt aufzurufen, indem man sie in Klammern einschließt.
Beispiel #8 Aufruf einer anonymen Funktion, die in einer Eigenschaft gespeichert ist
<?php
class Foo
{
public $bar;
public function __construct() {
$this->bar = function() {
return 42;
};
}
}
$obj = new Foo();
// von PHP 5.3.0 an:
$func = $obj->bar;
echo $func(), PHP_EOL;
// alternativ, von PHP 7.0.0 an:
echo ($obj->bar)(), PHP_EOL;
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
42
Eine Klasse kann Methoden und Eigenschaften einer anderen Klasse erben, indem man das extends-Schlüsselwort in der Deklaration benutzt. Es ist nicht möglich, mehrere Klassen zu erweitern; eine Klasse kann nur eine einzige Basisklasse beerben.
Die geerbten Methoden und Eigenschaften können durch eine Neudeklaration mit dem gleichen Namen wie in der Elternklasse überschrieben werden. Falls die Elternklasse eine Methode als final definiert hat, kann diese Methode nicht überschrieben werden. Es ist möglich, auf die überschriebenen Methoden oder statischen Eigenschaften zuzugreifen, wenn diese mittels parent:: referenziert werden.
Wenn Methoden überschrieben werden, sollte die Parametersignatur gleich
bleiben; andernfalls wird PHP einen E_STRICT
-Fehler
generieren. Dies gilt nicht für den Konstruktor, der das Überschreiben
mit unterschiedlichen Parameter erlaubt.
Beispiel #9 Einfache Vererbung
<?php
class ExtendClass extends SimpleClass
{
// Die Vatermethode überschreiben
function displayVar()
{
echo "Erweiternde Klasse\n";
parent::displayVar();
}
}
$extended = new ExtendClass();
$extended->displayVar();
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
Erweiternde Klasse ein Standardwert
Mit PHP 5.5 kann auch das Schlüsselwort class für die Namensauflösung einer Klasse verwendet werden. Man erhält den vollständig qualifizierten Namen der Klasse ClassName durch Verwendung von ClassName::class. Dies ist vor allem dann praktisch, wenn mit Namensräumen gearbeitet wird.
Beispiel #10 Auflösung von Klassennamen
<?php
namespace NS {
class ClassName {
}
echo ClassName::class;
}
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
NS\ClassName
Hinweis:
Bei der Auflösung des Klassennamens unter Verwendung von ::class handelt es sich um eine Transformation zur Übersetzungszeit. Das bedeutet, dass zu der Zeit, zu der die Klassennamen-Zeichenkette erzeugt wird, noch kein Autoloading erfolgt ist. Daraus folgt, dass Klassennamen erweitert werden, selbst wenn die Klasse nicht existiert. In diesem Fall wird kein Fehler erzeugt.