Бвойства

ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅-Ρ‡Π»Π΅Π½Ρ‹ класса Π½Π°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ свойствами. Π’ Π΄Ρ€ΡƒΠ³ΠΈΡ… языках Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Ρ‹Π΅ элСмСнты Π½Π°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ полями ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°ΠΌΠΈ, Π½ΠΎ Π² 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

Readonly-свойства

Начиная с 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].

οΌ‹Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΡ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ 4 notes

up
88
anca at techliminal dot com ΒΆ
10 years ago
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);
?>
up
66
Anonymous ΒΆ
15 years ago
$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).
up
28
zzzzBov ΒΆ
16 years ago
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.
up
0
anisgazira at gmail dot com ΒΆ
2 months ago
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+).