You can access property names with dashes in them (for example, because you converted an XML file to an object) in the following way:
<?php
$ref = new StdClass();
$ref->{'ref-type'} = 'Journal Article';
var_dump($ref);
?>
Variablen in einer Klasse werden Eigenschaften genannt.
Andere Begriffe wie Felder werden ebenfalls verwendet,
um sich auf dasselbe Konzept zu beziehen, aber innerhalb dieser Referenz
wird der Begriff Eigenschaften verwendet. Diese werden
definiert, indem mindestens ein Modifikator (wie
Sichtbarkeit,
Schlüsselwort static oder, seit PHP 8.1.0,
readonly)
verwendet wird, seit PHP 7.4 optional (außer für
readonly
-Eigenschaften) gefolgt von einer Typdeklaration,
gefolgt von einer regulären Variablendeklaration. Die Deklaration darf eine
Initialisierung des Variablenwertes beinhalten, der zu setzende Wert muss
dabei allerdings ein konstanter
Wert sein.
Hinweis:
Eine veraltete Art, Klasseneigenschaften zu deklarieren, ist die Verwendung des Schlüsselwors
var
anstelle eines Modifikators.
Hinweis: Eine Eigenschaft, die ohne Modifikator für Sichtbarkeit deklariert wird, wird als
public
deklariert.
Innerhalb der Methoden einer Klasse kann auf nicht-statische Eigenschaften
zugegriffen werden, indem man (den Objektoperator) ->
verwendet: $this->property (wobei
property
der Name der Eigenschaft ist). Zugriff auf
statische Eigenschaften erhält man, indem man (den Doppel-Doppelpunkt)
::
verwendet: self::$property. Siehe
auch Schlüsselwort static für mehr Informationen zu
diesem Thema.
Die Pseudo-Variable $this ist innerhalb jeder Klassenmethode verfügbar, wenn diese Methode im Kontext eines Objektes aufgerufen wird. $this ist der Wert des aufrufenden Objekts.
Beispiel #1 Deklaration von Eigenschaften
<?php
class SimpleClass
{
public $var1 = 'Hallo ' . 'Welt';
public $var2 = <<<EOD
Hallo Welt
EOD;
public $var3 = 1+2;
// Ungültige Deklarationen von Eigenschaften:
public $var4 = self::myStaticMethod();
public $var5 = $myVar;
// Gültige Deklarationen von Eigenschaften:
public $var6 = myConstant;
public $var7 = [true, false];
public $var8 = <<<'EOD'
Hallo Welt
EOD;
// Ohne Modifikator für Sichtbarkeit (Zugriffsrechte):
static $var9;
readonly int $var10;
}
?>
Hinweis:
Es gibt verschiedene Funktionen für den Umgang mit Klassen und Objekten. Siehe hierzu Klassen- und Objekt-Funktionen.
Von PHP 7.4.0 an können Eigenschaftsdefinitionen Typdeklarationen enthalten, mit Ausnahme des Typs callable.
Beispiel #2 Beispiel von typisierten Eigenschaften
<?php
class User
{
public int $id;
public ?string $name;
public function __construct(int $id, ?string $name)
{
$this->id = $id;
$this->name = $name;
}
}
$user = new User(1234, null);
var_dump($user->id);
var_dump($user->name);
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
int(1234) NULL
Typisierte Eigenschaften müssen vor dem Zugriff initialisiert werden, sonst wird ein Error ausgelöst.
Beispiel #3 Auf Eigenschaften zugreifen
<?php
class Shape
{
public int $numberOfSides;
public string $name;
public function setNumberOfSides(int $numberOfSides): void
{
$this->numberOfSides = $numberOfSides;
}
public function setName(string $name): void
{
$this->name = $name;
}
public function getNumberOfSides(): int
{
return $this->numberOfSides;
}
public function getName(): string
{
return $this->name;
}
}
$triangle = new Shape();
$triangle->setName("triangle");
$triangle->setNumberofSides(3);
var_dump($triangle->getName());
var_dump($triangle->getNumberOfSides());
$circle = new Shape();
$circle->setName("circle");
var_dump($circle->getName());
var_dump($circle->getNumberOfSides());
?>
Das oben gezeigte Beispiel erzeugt folgende Ausgabe:
string(8) "triangle" int(3) string(6) "circle" Fatal error: Uncaught Error: Typed property Shape::$numberOfSides must not be accessed before initialization
Seit PHP 8.1.0 ist es möglich, eine Eigenschaft mit
readonly
zu deklarieren. Dadurch wird verhindert, dass
die Eigenschaft nach der Initialisierung geändert wird. Vor PHP 8.4.0 ist
eine readonly
-Eigenschaft implizit auf privat gesetzt
und kann nur von derselben Klasse geschrieben werden. Ab PHP 8.4.0 sind
readonly
-Eigenschaften implizit
protected(set)
,
können also von Kindklassen aus definiert werden. Dies kann, falls
gewünscht, explizit überschrieben werden.
Beispiel #4 Beispiel für Readonly-Eigenschaften
<?php
class Test {
public readonly string $prop;
public function __construct(string $prop) {
// Korrekte Initialisierung.
$this->prop = $prop;
}
}
$test = new Test("foobar");
// Korrekt ausgelesen.
var_dump($test->prop); // string(6) "foobar"
// Unzulässige Neuzuweisung. Es spielt keine Rolle, dass der
// zugewiesene Wert derselbe ist.
$test->prop = "foobar";
// Error: Cannot modify readonly property Test::$prop
?>
Hinweis:
Der Modifikator readonly kann nur auf typisierte Eigenschaften angewendet werden. Wenn eine Eigenschaft ohne Typbeschränkung readonly sein soll, kann der Typ Mixed verwendet werden.
Hinweis:
Statische Readonly-Eigenschaften werden nicht unterstützt.
Eine Readonly-Eigenschaft kann nur einmal initialisiert werden, und zwar nur aus dem Bereich, in dem sie deklariert wurde. Jede andere Zuweisung oder Änderung der Eigenschaft führt zu einer Error-Exception.
Beispiel #5 Unzulässige Initialisierung von Readonly-Eigenschaften
<?php
class Test1 {
public readonly string $prop;
}
$test1 = new Test1;
// Unzulässige Initialisierung außerhalb des privaten Bereichs.
$test1->prop = "foobar";
// Error: Cannot initialize readonly property Test1::$prop from global scope
?>
Hinweis:
Die Angabe eines festen Standardwerts für Readonly-Eigenschaften ist nicht zulässig, da eine Readonly-Eigenschaft mit einem Standardwert im Wesentlichen dasselbe ist wie eine Konstante und daher nicht besonders nützlich.
<?php
class Test {
// Fatal error: Readonly property Test::$prop cannot have default value
public readonly int $prop = 42;
}
?>
Hinweis:
Readonly-Eigenschaften können nach der Initialisierung nicht mit unset() zurückgesetzt werden. Es ist jedoch möglich, eine Readonly-Eigenschaft vor der Initialisierung aus dem Bereich, in dem sie deklariert wurde, zurückzusetzen.
Änderungen sind nicht notwendigerweise einfache Zuweisungen; alle folgenden führen ebenfalls zu einer Error-Exception:
<?php
class Test {
public function __construct(
public readonly int $i = 0,
public readonly array $ary = [],
) {}
}
$test = new Test;
$test->i += 1;
$test->i++;
++$test->i;
$test->ary[] = 1;
$test->ary[0][] = 1;
$ref =& $test->i;
$test->i =& $ref;
byRef($test->i);
foreach ($test as &$prop);
?>
Readonly-Eigenschaften schließen jedoch nicht die interne Veränderbarkeit aus. Objekte (oder Ressourcen), die in Readonly-Eigenschaften gespeichert sind, können intern immer noch verändert werden:
<?php
class Test {
public function __construct(public readonly object $obj) {}
}
$test = new Test(new stdClass);
// Zulässige interne Änderung.
$test->obj->foo = 1;
// Unzulässige Neuzuweisung.
$test->obj = new stdClass;
?>
Seit PHP 8.3.0 können Eigenschaften, die nur gelesen werden können, beim Klonen eines Objekts mit der Methode __clone() neu initialisiert werden.
Beispiel #6 Readonly properties and cloning
<?php
class Test1 {
public readonly ?string $prop;
public function __clone() {
$this->prop = null;
}
public function setProp(string $prop): void {
$this->prop = $prop;
}
}
$test1 = new Test1;
$test1->setProp('foobar');
$test2 = clone $test1;
var_dump($test2->prop); // NULL
?>
Wenn man versucht, einem Objekt eine nicht existierende Eigenschaft zuzuweisen, erstellt PHP automatisch eine entsprechende Eigenschaft. Diese dynamisch erstellte Eigenschaft steht nur dieser Klasseninstanz zur Verfügung.
Dynamische Eigenschaften sind seit PHP 8.2.0 veraltet. Es wird empfohlen,
die Eigenschaft stattdessen zu deklarieren. Um mit beliebigen
Eigenschaftsnamen zu arbeiten, sollte die Klasse die magischen Methoden
__get() und
__set() implementieren. Als letzte
Möglichkeit kann die Klasse mit dem Attribut
#[\AllowDynamicProperties]
markiert werden.
You can access property names with dashes in them (for example, because you converted an XML file to an object) in the following way:
<?php
$ref = new StdClass();
$ref->{'ref-type'} = 'Journal Article';
var_dump($ref);
?>
$this can be cast to array. But when doing so, it prefixes the property names/new array keys with certain data depending on the property classification. Public property names are not changed. Protected properties are prefixed with a space-padded '*'. Private properties are prefixed with the space-padded class name...
<?php
class test
{
public $var1 = 1;
protected $var2 = 2;
private $var3 = 3;
static $var4 = 4;
public function toArray()
{
return (array) $this;
}
}
$t = new test;
print_r($t->toArray());
/* outputs:
Array
(
[var1] => 1
[ * var2] => 2
[ test var3] => 3
)
*/
?>
This is documented behavior when converting any object to an array (see </language.types.array.php#language.types.array.casting> PHP manual page). All properties regardless of visibility will be shown when casting an object to array (with exceptions of a few built-in objects).
To get an array with all property names unaltered, use the 'get_object_vars($this)' function in any method within class scope to retrieve an array of all properties regardless of external visibility, or 'get_object_vars($object)' outside class scope to retrieve an array of only public properties (see: </function.get-object-vars.php> PHP manual page).
Do not confuse php's version of properties with properties in other languages (C++ for example). In php, properties are the same as attributes, simple variables without functionality. They should be called attributes, not properties.
Properties have implicit accessor and mutator functionality. I've created an abstract class that allows implicit property functionality.
<?php
abstract class PropertyObject
{
public function __get($name)
{
if (method_exists($this, ($method = 'get_'.$name)))
{
return $this->$method();
}
else return;
}
public function __isset($name)
{
if (method_exists($this, ($method = 'isset_'.$name)))
{
return $this->$method();
}
else return;
}
public function __set($name, $value)
{
if (method_exists($this, ($method = 'set_'.$name)))
{
$this->$method($value);
}
}
public function __unset($name)
{
if (method_exists($this, ($method = 'unset_'.$name)))
{
$this->$method();
}
}
}
?>
after extending this class, you can create accessors and mutators that will be called automagically, using php's magic methods, when the corresponding property is accessed.