Die Grundlagen

class

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 ein beliebiger gültiger 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, wenn eine Methode aus einem Objektkontext heraus aufgerufen wird. $this ist eine Referenz auf das aufgerufene Objekt.

Warnung

Wird eine nicht-statische Methode statisch aufgerufen, so wird ein Error ausgelöst. Vor PHP 8.0.0 führte dies zu einem Hinweis über das veraltete Verfahren und $this war nicht definiert.

Beispiel #2 Einige Beispiele für die Pseudovariable $this

<?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 7:

$this ist definiert (A).

Deprecated: Non-static method A::foo() should not be called statically in %s  on line 27
$this ist nicht definiert.

Deprecated: Non-static method A::foo() should not be called statically in %s  on line 20
$this ist nicht definiert.

Deprecated: Non-static method B::bar() should not be called statically in %s  on line 32

Deprecated: Non-static method A::foo() should not be called statically in %s  on line 20
$this ist nicht definiert.

Das oben gezeigte Beispiel erzeugt mit PHP 8 folgende Ausgabe:

$this ist definiert (A).

Fatal error: Uncaught Error: Non-static method A::foo() cannot be called statically in %s :27
Stack trace:
#0 
  thrown in %s  on line 27

new

Um eine Instanz einer Klasse zu erzeugen, muss das Schlüsselwort new verwendet werden. Ein Objekt wird immer erzeugt, außer das Objekt besitzt einen definierten Konstruktor, der aufgrund eines Fehlers eine Exception auslöst. Klassen sollten vor ihrer Instantiierung definiert werden (in manchen Fällen ist dies eine Notwendigkeit).

Wenn ein String, der den Namen einer Klasse enthält, zusammen mit new verwendet wird, wird eine neue Instanz dieser Klasse erzeugt. Falls sich die Klasse in einem Namensraum befindet, muss der voll qualifizierte Name hierfür genutzt werden.

Hinweis:

Wenn dem Klassenkonstruktor keine Argumente übergeben werden müssen, 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()
?>

Seit PHP 8.0.0 wird die Verwendung von new mit beliebigen Ausdrücken unterstützt. Dies ermöglicht eine komplexere Instanziierung, sofern der Ausdruck einen String erzeugt. Die Ausdrücke müssen in Klammern eingeschlossen werden.

Beispiel #4 Erzeugen einer Instanz mit einem beliebigen Ausdruck

Hier werden mehrere Beispiele für gültige beliebige Ausdrücke gezeigt, die einen Klassennamen erzeugen. Enthalten ist ein Funktionsaufruf, eine String-Verkettung und die Konstante ::class.

<?php

class ClassA extends \stdClass {}
class 
ClassB extends \stdClass {}
class 
ClassC extends ClassB {}
class 
ClassD extends ClassA {}

function 
getSomeClass(): string
{
    return 
'ClassA';
}

var_dump(new (getSomeClass()));
var_dump(new ('Class' 'B'));
var_dump(new ('Class' 'C'));
var_dump(new (ClassD::class));
?>

Das oben gezeigte Beispiel erzeugt mit PHP 8 folgende Ausgabe:

object(ClassA)#1 (0) {
}
object(ClassB)#1 (0) {
}
object(ClassC)#1 (0) {
}
object(ClassD)#1 (0) {
}

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 dieselbe Instanz zugreifen wie das Objekt, das zugewiesen wurde. Dieses Verhalten ist dasselbe, wenn man Instanzen an Funktionen übergibt. Eine Kopie eines bereits erzeugten Objekts erhält man, indem man es klont.

Beispiel #5 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(34) "$zugewiesen wird diesen Wert haben"
}

Es gibt mehrere Möglichkeiten, Instanzen eines Objekts zu erzeugen:

Beispiel #6 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)

Es ist möglich, auf ein Mitglied eines neu erzeugten Objekts in einem einzigen Ausdruck zuzugreifen:

Beispiel #7 Zugriff auf ein Mitglied eines neu erzeugten Objekts

<?php
echo (new DateTime())->format('Y');
?>

Das oben gezeigte Beispiel erzeugt eine ähnliche Ausgabe wie:

2016

Hinweis: Vor PHP 7.1 werden die Argumente nicht ausgewertet, wenn keine Konstruktor-Funktion definiert ist.

Eigenschaften und Methoden

Klassen-Eigenschaften und -Methoden leben in separaten "Namensräumen", so dass es eine Eigenschaft und eine Methode desselben Namens geben kann. Der Zugriff auf eine Eigenschaft und eine Methode hat die gleiche Schreibweise 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 #8 Variablenzugriff vs. Methodenaufruf

<?php
class Foo
{
    public 
$bar 'Eigenschaft';

    public function 
bar() {
        return 
'Methode';
    }
}

$obj = new Foo();
echo 
$obj->barPHP_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. Stattdessen muss beispielsweise die Eigenschaft zunächst einer Variablen zugewiesen werden. Es ist möglich, eine solche Eigenschaft direkt aufzurufen, indem man sie in Klammern einschließt.

Beispiel #9 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();

echo (
$obj->bar)(), PHP_EOL;

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

42

extends

Eine Klasse kann die Konstanten, Methoden und Eigenschaften einer anderen Klasse erben, indem man das Schlüsselwort extends in der Deklaration benutzt. Es ist nicht möglich, mehrere Klassen zu erweitern; eine Klasse kann nur eine einzige Basisklasse beerben.

Die geerbten Konstanten, Methoden und Eigenschaften können überschrieben werden, indem sie mit demselben Namen neu deklariert werden, mit dem sie in der Elternklasse definiert wurden. Falls die Elternklasse eine Methode oder eine Konstante als final definiert hat, können diese nicht überschrieben werden. Es ist möglich, auf die überschriebenen Methoden oder statischen Eigenschaften zuzugreifen, wenn diese mittels parent:: referenziert werden.

Hinweis: Seit PHP 8.1.0 können Konstanten als final deklariert werden.

Beispiel #10 Einfache Vererbung

<?php
class ExtendClass extends SimpleClass
{
    
// Die Elternmethode ü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

Regeln zur Signaturkompatibilität

Wenn eine Methode überschrieben wird, so muss deren Signatur mit derjenigen der Elternmethode kompatibel sein. Andernfalls wird ein fataler Fehler hervorgerufen oder, vor PHP 8.0.0, eine Warnung der Stufe E_WARNING ausgegeben. Eine Signatur ist kompatibel, wenn sie die Regeln zur Varianz berücksichtigt, einen notwendigen Parameter optional macht und alle neuen Parameter optional sind. Dies ist als das Liskovsche Substitutionsprinzip, kurz LSP, bekannt. Der Konstruktor sowie private Methoden sind von diesen Regeln zur Signaturkompatibilität ausgenommen, weshalb im Fall einer Untimmigkeit in der Signatur kein fataler Fehler hervorgerufen wird.

Beispiel #11 Kompatible Kindmethoden

<?php

class Base
{
    public function 
foo(int $a) {
        echo 
"Gültig\n";
    }
}

class 
Extend1 extends Base
{
    function 
foo(int $a 5)
    {
        
parent::foo($a);
    }
}

class 
Extend2 extends Base
{
    function 
foo(int $a$b 5)
    {
        
parent::foo($a);
    }
}

$extended1 = new Extend1();
$extended1->foo();
$extended2 = new Extend2();
$extended2->foo(1);

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

Gültig
Gültig

Das folgende Beispiel demonstriert, dass eine Kindmethode nicht zur Elternmethode kompatibel ist, wenn sie einen Parameter entfernt oder einen optionalen Parameter notwendig macht.

Beispiel #12 Fataler Fehler, wenn eine Kindmethode einen Parameter entfernt

<?php

class Base
{
    public function 
foo(int $a 5) {
        echo 
"Gültig\n";
    }
}

class 
Extend extends Base
{
    function 
foo()
    {
        
parent::foo(1);
    }
}

Das oben gezeigte Beispiel erzeugt mit PHP 8 eine ähnliche Ausgabe wie:

Fatal error: Declaration of Extend::foo() must be compatible with Base::foo(int $a = 5) in /in/evtlq on line 13

Beispiel #13 Fataler Fehler, wenn eine Kindmethode einen optionalen Parameter notwendig macht

<?php

class Base
{
    public function 
foo(int $a 5) {
        echo 
"Gültig\n";
    }
}

class 
Extend extends Base
{
    function 
foo(int $a)
    {
        
parent::foo($a);
    }
}

Das oben gezeigte Beispiel erzeugt mit PHP 8 eine ähnliche Ausgabe wie:

Fatal error: Declaration of Extend::foo(int $a) must be compatible with Base::foo(int $a = 5) in /in/qJXVC on line 13
Warnung

Die Umbenennung eines Parameters einer Methode in einer Kindklasse führt nicht zur Inkompatibilität. Es wird jedoch davon abgeraten, da es zu Fehlern der Stufe Error führt, wenn benannte Parameter verwendet werden.

Beispiel #14 Fehler, wenn benannte Parameter verwendet und diese in der Kindklasse umbenannt werden

<?php

class {
    public function 
test($foo$bar) {}
}

class 
extends {
    public function 
test($a$b) {}
}

$obj = new B;

// Übergabe der Parameter gemäß den Konventionen von A::test()
$obj->test(foo"foo"bar"bar"); // ERROR!

Das oben gezeigte Beispiel erzeugt eine ähnliche Ausgabe wie:

Fatal error: Uncaught Error: Unknown named parameter $foo in /in/XaaeN:14
Stack trace:
#0 
  thrown in /in/XaaeN on line 14

::class

Das Schlüsselwort class kann auch für die Namensauflösung einer Klasse verwendet werden. Um den vollständig qualifizierten Namen der Klasse ClassName zu erhalten, kann ClassName::class verwendet werden. Dies ist vor allem dann praktisch, wenn mit Namensräumen gearbeitet wird.

Beispiel #15 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.

Beispiel #16 Fehlende Auflösung des Klassennamens

<?php
print Does\Not\Exist::class;
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

Does\Not\Exist

Von PHP 8.0.0 an kann die Konstante ::class auch auf Objekte angewendet werden. Diese Auflösung des Klassennamens erfolgt nicht zur Übersetzungszeit, sondern zur Laufzeit. Sie hat die gleichen Auswirkungen wie der Aufruf von get_class() auf das Objekt.

Beispiel #17 Namensauflösung eines Objekts

<?php
namespace NS {
    class 
ClassName {
    }
}
$c = new ClassName();
print 
$c::class;
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

NS\ClassName

Nullsafe-Methoden und -Eigenschaften

Von PHP 8.0.0 an kann auf Eigenschaften und Methoden stattdessen auch mit dem "Nullsafe"-Operator zugegriffen werden: ?->. Der Nullsafe-Operator funktioniert genauso als Eigenschafts- oder Methodenzugriff wie oben, mit dem Unterschied, dass null zurückgegeben wird, statt dass eine Exception erzeugt wird, wenn das Objekt, das dereferenziert wird, null ist. Wenn die Dereferenzierung Teil einer Zeichenkette ist, wird der Rest der Zeichenkette übersprungen.

Der Effekt ist ähnlich, wie wenn man jeden Zugriff zuerst mit is_null() prüft, aber kompakter.

Beispiel #18 Nullsafe Operator

<?php

// Von PHP 8.0.0 an entspricht diese Zeile:
$result $repository?->getUser(5)?->name;

// dem folgenden Codeblock:
if (is_null($repository)) {
    
$result null;
} else {
    
$user $repository->getUser(5);
    if (
is_null($user)) {
        
$result null;
    } else {
        
$result $user->name;
    }
}
?>

Hinweis:

Der Nullsafe-Operator wird am besten verwendet, wenn Null ein gültiger und potenziell erwarteter möglicher Rückgabewert für eine Eigenschaft oder eine Methode ist. Um einen Fehler anzuzeigen, ist die Erzeugung einer Exception vorzuziehen.

Hier Kannst Du einen Kommentar verfassen


Bitte gib mindestens 10 Zeichen ein.
Wird geladen... Bitte warte.
* Pflichtangabe
Es sind noch keine Kommentare vorhanden.

Abmahnwelle durch Google Fonts - was ist zu beachten und wie schütze ich mich?

Abmahnwelle durch Google Fonts - was ist zu beachten und wie schütze ich mich?

Eine Abmahnwelle wegen Google Fonts rollt derzeit durch das Land und verunsichert viele Betreiber von Webseiten. Ausschlaggebend hierfür war ein Urteil des Landgerichts München vom 20.01.2022. ...

Bernie

Autor : ebiz-consult GmbH & Co. KG
Kategorie: Dies und Das

Was zeichnet einen Full-Stack-Webentwickler aus und welche Fähigkeiten muss ein Full-Stack-Webentwickler besitzen?

In immer mehr Stellenausschreibungen liest man den Begriff "Full-Stack-Webentwickler". Was aber macht einen Full-Stack-Webentwickler eigentlich aus? Welche Themen der Webentwicklung sollte er abdecken können? ...

TheMax

Autor : TheMax
Kategorie: PHP Magazin

phpFox 4.8.11 erschienen

phpFox, ein professionelles Facebook Clone Script ist in der Version 4.8.11 erschienen ...

PhpFox

Autor : PhpFox
Kategorie: Firmennews & Pressemitteilungen

Tutorial veröffentlichen

Tutorial veröffentlichen

Teile Dein Wissen mit anderen Entwicklern weltweit

Du bist Profi in deinem Bereich und möchtest dein Wissen teilen, dann melde dich jetzt an und teile es mit unserer PHP-Community

mehr erfahren

Tutorial veröffentlichen

Text import mit š

leider habe ich keinen Ansatz mehr, habe nun behelfsmäßig alle betreffenden Zeichen im csv als Zeichen wie & oder % gesetzt und diese dann mit r ...

Geschrieben von jamessbuzzz am 01.12.2022 15:02:54
Forum: PHP Developer Forum
eMail Neuregistrierung

Besser spät als nie: Es gab einen Relaunch mit dem wir sowohl das Forum als auch den Rest der Webseite mal etwas modernisiert haben. Im Zuge der ...

Geschrieben von Jens am 28.11.2022 15:42:59
Forum: News / Kostenloses
.htaccess

Kannst du vielleicht mit 1-2 Beispielen ausführen was du erwartest und wie das tatsächliche Verhalten ist? So spontan würde ich erwarten, dass ...

Paginator - Normale Abfrage klappt einwandfrei ...

Das nennt sich "seitenweises blättern". Du musst mit Links und den entsprechenden Parametern arbeiten. Ich habe anno dunnemals dazu ein Tutorial ...

Geschrieben von Kropff am 25.11.2022 18:07:20
Forum: PHP Developer Forum