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);
?>
ΠΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅-ΡΠ»Π΅Π½Ρ ΠΊΠ»Π°ΡΡΠ° Π½Π°Π·ΡΠ²Π°ΡΡΡΡ ΡΠ²ΠΎΠΉΡΡΠ²Π°ΠΌΠΈ.
Π Π΄ΡΡΠ³ΠΈΡ
ΡΠ·ΡΠΊΠ°Ρ
Π°Π½Π°Π»ΠΎΠ³ΠΈΡΠ½ΡΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ Π½Π°Π·ΡΠ²Π°ΡΡΡΡ ΠΏΠΎΠ»ΡΠΌΠΈ ΠΈ Π΄ΡΡΠ³ΠΈΠΌΠΈ ΡΠ΅ΡΠΌΠΈΠ½Π°ΠΌΠΈ,
Π½ΠΎ Π² PHP-Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ
ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅-ΡΠ»Π΅Π½Ρ ΠΊΠ»Π°ΡΡΠ° Π½Π°Π·ΡΠ²Π°ΡΡΡΡ ΡΠ²ΠΎΠΉΡΡΠ²Π°ΠΌΠΈ.
Π‘Π²ΠΎΠΉΡΡΠ²Π° ΠΊΠ»Π°ΡΡΠ° ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΡΡ Ρ
ΠΎΡΡ Π±Ρ ΠΎΠ΄Π½ΠΈΠΌ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠΌ (ΠΊΠΎΡΠΎΡΡΠ΅ ΠΎΠΏΠΈΡΡΠ²Π°ΡΡ ΡΠ°Π·Π΄Π΅Π»Ρ
Β«ΠΠ±Π»Π°ΡΡΡ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈΒ», Β«ΠΠ»ΡΡΠ΅Π²ΠΎΠ΅ ΡΠ»ΠΎΠ²ΠΎ staticΒ»
ΠΈΠ»ΠΈ Π½Π°ΡΠΈΠ½Π°Ρ Ρ PHP 8.1.0 readonly),
Π·Π° ΠΊΠΎΡΠΎΡΡΠΌ Π½Π°ΡΠΈΠ½Π°Ρ Ρ PHP 7.4 ΡΠ»Π΅Π΄ΡΠ΅Ρ Π½Π΅ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎΠ΅, Π·Π° ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ΠΌ readonly-ΡΠ²ΠΎΠΉΡΡΠ²,
ΠΎΠ±ΡΡΠ²Π»Π΅Π½ΠΈΠ΅ ΡΠΈΠΏΠ°, ΠΏΠΎΡΠ»Π΅ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ ΠΈΠ΄ΡΡ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎΠ΅ ΠΎΠ±ΡΡΠ²Π»Π΅Π½ΠΈΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ.
ΠΡΠΈ ΠΎΠ±ΡΡΠ²Π»Π΅Π½ΠΈΠΈ ΡΠ²ΠΎΠΉΡΡΠ²Π° ΠΊΠ»Π°ΡΡΠ° ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ,
Π½ΠΎ Π½Π°ΡΠ°Π»ΡΠ½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΏΠΎΡΡΠ΅Π±ΡΠ΅ΡΡΡ ΡΠΊΠ°Π·Π°ΡΡ
ΠΊΠ°ΠΊ ΠΏΠΎΡΡΠΎΡΠ½Π½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅.
ΠΠ°ΠΌΠ΅ΡΠ°Π½ΠΈΠ΅:
Π£ΡΡΠ°ΡΠ΅Π²ΡΠΈΠΉ ΡΠΏΠΎΡΠΎΠ± ΠΎΠ±ΡΡΠ²Π»Π΅Π½ΠΈΡ ΡΠ²ΠΎΠΉΡΡΠ² ΠΊΠ»Π°ΡΡΠ° β ΠΊΠ»ΡΡΠ΅Π²ΠΎΠ΅ ΡΠ»ΠΎΠ²ΠΎ
varΠ²ΠΌΠ΅ΡΡΠΎ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡΠ°.
ΠΠ°ΠΌΠ΅ΡΠ°Π½ΠΈΠ΅: Π‘Π²ΠΎΠΉΡΡΠ²ΠΎ, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΎΠ±ΡΡΠ²ΠΈΠ»ΠΈ Π±Π΅Π· ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡΠ° ΡΠ°Π·Π΄Π΅Π»Π° Β«ΠΠ±Π»Π°ΡΡΡ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈΒ», PHP ΠΎΠ±ΡΡΠ²ΠΈΡ ΠΊΠ°ΠΊ
public.
ΠΠ½ΡΡΡΠΈ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ² ΠΊΠ»Π°ΡΡΠ° Π΄ΠΎΡΡΡΠΏ ΠΊ Π½Π΅ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΌ ΡΠ²ΠΎΠΉΡΡΠ²Π°ΠΌ ΠΏΠΎΠ»ΡΡΠ°ΡΡ
ΡΠ΅ΡΠ΅Π· ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡ ΠΎΠ±ΡΠ΅ΠΊΡΠ° -> β
$this->property, Π³Π΄Π΅ property β ΠΈΠΌΡ ΡΠ²ΠΎΠΉΡΡΠ²Π°.
ΠΠΎΡΡΡΠΏ ΠΊ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΌ ΡΠ²ΠΎΠΉΡΡΠ²Π°ΠΌ ΠΏΠΎΠ»ΡΡΠ°ΡΡ ΡΠ΅ΡΠ΅Π· ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡ Π΄Π²ΠΎΠΉΠ½ΠΎΠ³ΠΎ Π΄Π²ΠΎΠ΅ΡΠΎΡΠΈΡ :: β
self::$property. ΠΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎΠ± ΠΎΡΠ»ΠΈΡΠΈΡΡ
ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΡ
ΡΠ²ΠΎΠΉΡΡΠ² ΠΎΡ Π½Π΅ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΡ
Π΄Π°ΡΡ ΡΠ°Π·Π΄Π΅Π»
Β«ΠΠ»ΡΡΠ΅Π²ΠΎΠ΅ ΡΠ»ΠΎΠ²ΠΎ staticΒ».
ΠΡΠ΅Π²Π΄ΠΎΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ $this Π΄ΠΎΡΡΡΠΏΠ½Π° Π²Π½ΡΡΡΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΌΠ΅ΡΠΎΠ΄Π° ΠΊΠ»Π°ΡΡΠ°, Π΅ΡΠ»ΠΈ ΠΌΠ΅ΡΠΎΠ΄ Π²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ ΠΈΠ· ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ° ΠΎΠ±ΡΠ΅ΠΊΡΠ°. ΠΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ $this β Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π²ΡΠ·ΡΠ²Π°ΡΡΠ΅Π³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ°.
ΠΡΠΈΠΌΠ΅Ρ #1 ΠΠ±ΡΡΠ²Π»Π΅Π½ΠΈΠ΅ ΡΠ²ΠΎΠΉΡΡΠ²
<?php
class SimpleClass
{
public $var1 = 'hello ' . 'world';
public $var2 = <<<EOD
hello world
EOD;
public $var3 = 1+2;
// ΠΠ΅ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎΠ΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΡΠ²ΠΎΠΉΡΡΠ²:
public $var4 = self::myStaticMethod();
public $var5 = $myVar;
// ΠΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎΠ΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΡΠ²ΠΎΠΉΡΡΠ²:
public $var6 = myConstant;
public $var7 = [true, false];
public $var8 = <<<'EOD'
hello world
EOD;
// ΠΠ΅Π· ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡΠ° ΠΎΠ±Π»Π°ΡΡΠΈ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ:
static $var9;
readonly int $var10;
}ΠΠ°ΠΌΠ΅ΡΠ°Π½ΠΈΠ΅:
ΠΠ»Π°ΡΡΡ ΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ Π½Π°Π±ΠΎΡΠΎΠΌ ΡΡΠ½ΠΊΡΠΈΠΉ. Π‘ΠΌΠΎΡΡΠΈΡΠ΅ ΡΠ°Π·Π΄Π΅Π» ΡΠΏΡΠ°Π²ΠΊΠΈ Β«Π€ΡΠ½ΠΊΡΠΈΠΈ ΡΠ°Π±ΠΎΡΡ Ρ ΠΊΠ»Π°ΡΡΠ°ΠΌΠΈ ΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΠ°ΠΌΠΈΒ».
ΠΠ°ΡΠΈΠ½Π°Ρ Ρ PHP 7.4.0 ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡΠΌ ΡΠ²ΠΎΠΉΡΡΠ² ΡΠ°Π·ΡΠ΅ΡΠ°Π΅ΡΡΡ Π²ΠΊΠ»ΡΡΠ°ΡΡ Β«ΠΠ±ΡΡΠ²Π»Π΅Π½ΠΈΡ ΡΠΈΠΏΠΎΠ²Β», Π·Π° ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ΠΌ ΡΠΈΠΏΠ° callable.
ΠΡΠΈΠΌΠ΅Ρ #2 ΠΡΠΈΠΌΠ΅Ρ ΡΠΈΠΏΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΡΡ ΡΠ²ΠΎΠΉΡΡΠ²
<?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);Π Π΅Π·ΡΠ»ΡΡΠ°Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΏΡΠΈΠ²Π΅Π΄ΡΠ½Π½ΠΎΠ³ΠΎ ΠΏΡΠΈΠΌΠ΅ΡΠ°:
int(1234) NULL
ΠΡΠΈ ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΠΈ ΠΊ ΡΠΈΠΏΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΌΡ ΡΠ²ΠΎΠΉΡΡΠ²Ρ, Π΄Π»Ρ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ Π½Π΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΠ»ΠΈ Π½Π°ΡΠ°Π»ΡΠ½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅, PHP Π²ΡΠ±ΡΠΎΡΠΈΡ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Error.
ΠΡΠΈΠΌΠ΅Ρ #3 ΠΠ±ΡΠ°ΡΠ΅Π½ΠΈΠ΅ ΠΊ ΡΠ²ΠΎΠΉΡΡΠ²Π°ΠΌ
<?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());Π Π΅Π·ΡΠ»ΡΡΠ°Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΏΡΠΈΠ²Π΅Π΄ΡΠ½Π½ΠΎΠ³ΠΎ ΠΏΡΠΈΠΌΠ΅ΡΠ°:
string(8) "triangle" int(3) string(6) "circle" Fatal error: Uncaught Error: Typed property Shape::$numberOfSides must not be accessed before initialization
ΠΠ°ΡΠΈΠ½Π°Ρ Ρ PHP 8.1.0 ΡΠ°Π·ΡΠ΅ΡΠΈΠ»ΠΈ ΠΎΠ±ΡΡΠ²Π»ΡΡΡ ΡΠ²ΠΎΠΉΡΡΠ²Π° Ρ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠΌ readonly,
ΠΊΠΎΡΠΎΡΡΠΉ Π·Π°ΠΏΡΠ΅ΡΠ°Π΅Ρ ΠΈΠ·ΠΌΠ΅Π½ΡΡΡ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ ΠΏΠΎΡΠ»Π΅ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ.
ΠΠΎ PHP 8.4.0 ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ Ρ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠΌ readonly
Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΏΠΎΠ»ΡΡΠ°Π»ΠΎ Π·Π°ΠΊΡΡΡΡΡ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΡ Π΄Π»Ρ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ Π·Π½Π°ΡΠ΅Π½ΠΈΡ,
ΠΈ Π·Π°ΠΏΠΈΡΡΠ²Π°ΡΡ ΡΠ°ΠΊΠΎΠ΅ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ ΡΠΎΠ»ΡΠΊΠΎ Π² ΡΠΎΠΌ ΠΆΠ΅ ΡΠ°ΠΌΠΎΠΌ ΠΊΠ»Π°ΡΡΠ΅, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ ΠΎΠ±ΡΡΠ²ΠΈΠ»ΠΈ.
Π‘ PHP 8.4.0 ΡΠ²ΠΎΠΉΡΡΠ²Π° Ρ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠΌ readonly
Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΏΠΎΠ»ΡΡΠ°ΡΡ Π·Π°ΡΠΈΡΡΠ½Π½ΡΡ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΡ Π΄Π»Ρ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ Π·Π½Π°ΡΠ΅Π½ΠΈΡ
protected(set),
ΠΏΠΎΡΡΠΎΠΌΡ ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ Π΄Π»Ρ ΡΠ°ΠΊΠΎΠ³ΠΎ ΡΠ²ΠΎΠΉΡΡΠ²Π° ΠΌΠΎΠΆΠ½ΠΎ Π² Π΄ΠΎΡΠ΅ΡΠ½Π΅ΠΌ ΠΊΠ»Π°ΡΡΠ΅.
ΠΠΈΠ΄ΠΈΠΌΠΎΡΡΡ ΡΠ²ΠΎΠΉΡΡΠ²Π° Π΄Π»Ρ Π·Π°ΠΏΠΈΡΠΈ ΡΠ°Π·ΡΠ΅ΡΠ°Π΅ΡΡΡ ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΡΡ Π²ΡΡΡΠ½ΡΡ.
ΠΡΠΈΠΌΠ΅Ρ #4 ΠΡΠΈΠΌΠ΅ΡΡ readonly-ΡΠ²ΠΎΠΉΡΡΠ²
<?php
class Test
{
public readonly string $prop;
public function __construct(string $prop)
{
// ΠΡΠ°Π²ΠΈΠ»ΡΠ½Π°Ρ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ.
$this->prop = $prop;
}
}
$test = new Test("foobar");
// ΠΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎΠ΅ ΡΡΠ΅Π½ΠΈΠ΅
var_dump($test->prop); // string(6) "foobar"
// ΠΠ΅ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎΠ΅ ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅. ΠΠ΅ ΠΈΠΌΠ΅Π΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΡ, ΡΡΠΎ ΠΏΡΠΈΡΠ²ΠΎΠ΅Π½Π½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΠ°ΠΊΠΎΠ΅ ΠΆΠ΅
$test->prop = "foobar";
// Error: Cannot modify readonly property Test::$propΠΠ°ΠΌΠ΅ΡΠ°Π½ΠΈΠ΅:
ΠΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΎΡ readonly ΡΠ°Π·ΡΠ΅ΡΠ°Π΅ΡΡΡ ΠΏΡΠΈΠΌΠ΅Π½ΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΠΊ ΡΠΈΠΏΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΡΠΌ ΡΠ²ΠΎΠΉΡΡΠ²Π°ΠΌ. Π’ΠΈΠΏ ΡΠ²ΠΎΠΉΡΡΠ²Π° ΠΎΠ±ΡΡΠ²Π»ΡΡΡ ΠΊΠ°ΠΊ Mixed, ΠΊΠΎΠ³Π΄Π° ΡΡΠ΅Π±ΡΠ΅ΡΡΡ ΡΠΎΠ·Π΄Π°ΡΡ readonly-ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ Π±Π΅Π· ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠΉ ΡΠΈΠΏΠ°.
ΠΠ°ΠΌΠ΅ΡΠ°Π½ΠΈΠ΅:
Π‘ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ readonly-ΡΠ²ΠΎΠΉΡΡΠ²Π° Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡΡΡ.
Readonly-ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ ΡΠ°Π·ΡΠ΅ΡΠ°Π΅ΡΡΡ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΡΠ°Π· ΠΈ ΡΠΎΠ»ΡΠΊΠΎ ΠΈΠ· ΠΎΠ±Π»Π°ΡΡΠΈ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ ΠΎΠ±ΡΡΠ²ΠΈΠ»ΠΈ. ΠΡΡΠ³ΠΎΠ΅ ΠΏΡΠΈΡΠ²Π°ΠΈΠ²Π°Π½ΠΈΠ΅ ΠΈΠ»ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΡΠ²ΠΎΠΉΡΡΠ²Π° ΠΏΡΠΈΠ²Π΅Π΄ΡΡ ΠΊ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ Error.
ΠΡΠΈΠΌΠ΅Ρ #5 ΠΠ΅ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½Π°Ρ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ readonly-ΡΠ²ΠΎΠΉΡΡΠ²
<?php
class Test1
{
public readonly string $prop;
}
$test1 = new Test1();
// ΠΠ΅ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½Π°Ρ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ Π·Π° ΠΏΡΠ΅Π΄Π΅Π»Π°ΠΌΠΈ Π·Π°ΠΊΡΡΡΠΎΠΉ ΠΎΠ±Π»Π°ΡΡΠΈ
$test1->prop = "foobar";
// Error: Cannot initialize readonly property Test1::$prop from global scopeΠΠ°ΠΌΠ΅ΡΠ°Π½ΠΈΠ΅:
ΠΠ΅Π»ΡΠ·Ρ ΡΠ²Π½ΡΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ ΡΠΊΠ°Π·ΡΠ²Π°ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ Π΄Π»Ρ readonly-ΡΠ²ΠΎΠΉΡΡΠ², ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ readonly-ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ ΡΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ΠΌ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ ΠΏΠΎ ΡΡΡΠ΅ΡΡΠ²Ρ ΡΠΎΠ²ΠΏΠ°Π΄Π°Π΅Ρ Ρ ΠΊΠΎΠ½ΡΡΠ°Π½ΡΠΎΠΉ, ΠΈ ΠΏΠΎΡΡΠΎΠΌΡ Π±Π΅ΡΠΏΠΎΠ»Π΅Π·Π½ΠΎ.
<?php
class Test
{
// Error: Readonly property Test::$prop cannot have default value
public readonly int $prop = 42;
}
ΠΠ°ΠΌΠ΅ΡΠ°Π½ΠΈΠ΅:
ΠΠΎΠ½ΡΡΡΡΠΊΡΠΈΠ΅ΠΉ unset() Π½Π΅Π»ΡΠ·Ρ ΡΠ½ΠΈΡΡΠΎΠΆΠΈΡΡ readonly-ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ ΠΏΠΎΡΠ»Π΅ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ. ΠΠ΄Π½Π°ΠΊΠΎ ΠΏΠΎΠ»ΡΡΠΈΡΡΡ ΡΠ½ΠΈΡΡΠΎΠΆΠΈΡΡ readonly-ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ Π΄ΠΎ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΈΠ· ΠΎΠ±Π»Π°ΡΡΠΈ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ ΠΎΠ±ΡΡΠ²ΠΈΠ»ΠΈ.
Π ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡΠΌ ΠΎΡΠ½ΠΎΡΡΡΡΡ Π½Π΅ ΡΠΎΠ»ΡΠΊΠΎ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠ΅ ΠΏΡΠΈΡΠ²Π°ΠΈΠ²Π°Π½ΠΈΡ, ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ ΡΠΎΠΆΠ΅ Π²ΡΠ±ΡΠΎΡΡΡ ΠΎΡΠΈΠ±ΠΊΡ Error:
<?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;
unset($test->ary[0]);
$ref =& $test->i;
$test->i =& $ref;
byRef($test->i);
foreach ($test as &$prop);ΠΡΠΈ ΡΡΠΎΠΌ readonly-ΡΠ²ΠΎΠΉΡΡΠ²Π° Π½Π΅ ΠΈΡΠΊΠ»ΡΡΠ°ΡΡ Π²Π½ΡΡΡΠ΅Π½Π½ΡΡ ΠΈΠ·ΠΌΠ΅Π½ΡΠΈΠ²ΠΎΡΡΡ. ΠΠ±ΡΠ΅ΠΊΡΡ ΠΈ ΡΠ΅ΡΡΡΡΡ, ΠΊΠΎΡΠΎΡΡΠ΅ Ρ ΡΠ°Π½ΡΡΡΡ Π² readonly-ΡΠ²ΠΎΠΉΡΡΠ²Π°Ρ , ΠΏΠΎ-ΠΏΡΠ΅ΠΆΠ½Π΅ΠΌΡ ΠΏΠΎΠ»ΡΡΠΈΡΡΡ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡΡ Π²Π½ΡΡΡΠΈ:
<?php
class Test
{
public function __construct(public readonly object $obj) {}
}
$test = new Test(new stdClass());
// ΠΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎΠ΅ Π²Π½ΡΡΡΠ΅Π½Π½Π΅Π΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅
$test->obj->foo = 1;
// ΠΠ΅ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎΠ΅ ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅
$test->obj = new stdClass();ΠΠ°ΡΠΈΠ½Π°Ρ Ρ PHP 8.3.0 ΡΠ²ΠΎΠΉΡΡΠ²Π°, Π΄ΠΎΡΡΡΠΏΠ½ΡΠ΅ ΡΠΎΠ»ΡΠΊΠΎ Π΄Π»Ρ ΡΡΠ΅Π½ΠΈΡ, ΡΠ°Π·ΡΠ΅ΡΠ°Π΅ΡΡΡ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎ ΠΏΡΠΈ ΠΊΠ»ΠΎΠ½ΠΈΡΠΎΠ²Π°Π½ΠΈΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΠ° ΡΠ΅ΡΠ΅Π· ΠΌΠ°Π³ΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΌΠ΅ΡΠΎΠ΄ __clone().
ΠΡΠΈΠΌΠ΅Ρ #6 ΠΠ»ΠΎΠ½ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ readonly-ΡΠ²ΠΎΠΉΡΡΠ²
<?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ΠΡΠΈ ΠΏΠΎΠΏΡΡΠΊΠ΅ ΠΏΡΠΈΡΠ²ΠΎΠΈΡΡ Π½Π΅ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠ΅Π΅ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΡ (object), PHP Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΡΠΎΠ·Π΄Π°ΡΡ ΡΠ°ΠΊΠΎΠ΅ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ. ΠΡΠΎ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈ ΡΠΎΠ·Π΄Π°Π½Π½ΠΎΠ΅ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ Π±ΡΠ΄Π΅Ρ Π΄ΠΎΡΡΡΠΏΠ½ΠΎ ΡΠΎΠ»ΡΠΊΠΎ Π΄Π»Ρ ΡΡΠΎΠ³ΠΎ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ° ΠΊΠ»Π°ΡΡΠ°.
Π‘ PHP 8.2.0 Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΡΠ²ΠΎΠΉΡΡΠ²Π° ΡΡΡΠ°ΡΠ΅Π»ΠΈ.
ΠΠΌΠ΅ΡΡΠΎ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ ΠΏΡΠΈΡΠ²Π°ΠΈΠ²Π°Π½ΠΈΡ ΡΠ²ΠΎΠΉΡΡΠ²Π° ΠΊΠ»Π°ΡΡΡ ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΡΡ ΠΎΠ±ΡΡΠ²Π»ΡΡΡ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ.
ΠΠ»Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»ΡΠ½ΡΡ
ΠΈΠΌΡΠ½ ΡΠ²ΠΎΠΉΡΡΠ²
ΠΊΠ»Π°ΡΡ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΠΌΠ°Π³ΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΌΠ΅ΡΠΎΠ΄Ρ
__get() ΠΈ __set().
Π ΠΊΡΠ°ΠΉΠ½Π΅ΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΊΠ»Π°ΡΡ ΠΏΠΎΠΌΠ΅ΡΠ°ΡΡ Π°ΡΡΠΈΠ±ΡΡΠΎΠΌ #[\AllowDynamicProperties].
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.When declaring class properties in PHP, keep the following rules in mind:
A property must have a visibility modifier (public, protected, or private).
You may optionally use type declarations (available since PHP 7.4).
If you assign a default value, it must be a constant expression.
This means you can only assign fixed values such as integers, strings, booleans, or constants. You cannot use function calls or any runtime-evaluated expressions.
Example (valid):
class Test {
public int $x = 10;
public string $name = "Rahim";
public bool $flag = true;
}
Example (invalid):
class Test {
public int $x = rand(); // Fatal error: constant expression required
}
The reason is that property defaults are evaluated at compile time, while functions like rand() are executed at runtime.
If you need dynamic values, assign them inside the constructor or a method:
class Test {
public int $x;
public function __construct() {
$this->x = rand(); // OK
}
}
Note: This rule applies whether or not you use typed properties (PHP 7.4+).