ΠœΠ°Π³ΠΈΡ‡Π΅ΡΠΊΠΈΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹

ΠœΠ°Π³ΠΈΡ‡Π΅ΡΠΊΠΈΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ β€” ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ дСйствиС PHP ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, ΠΊΠΎΠ³Π΄Π° Π½Π°Π΄ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ дСйствия.

ΠŸΡ€Π΅Π΄ΠΎΡΡ‚Π΅Ρ€Π΅ΠΆΠ΅Π½ΠΈΠ΅

Названия ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‚ΡΡ с Π΄Π²ΡƒΡ… символов подчёркивания __, Π·Π°Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΠΎΠ²Π°Π»ΠΈ Π² PHP, поэтому Π»ΡƒΡ‡ΡˆΠ΅ Π½Π΅ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌ Ρ‚Π°ΠΊΠΈΠ΅ названия, Ссли Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π΅ трСбуСтся ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ PHP.

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ названия ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² относятся ΠΊ магичСским: __construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __serialize(), __unserialize(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone() ΠΈ __debugInfo()

Π’Π½ΠΈΠΌΠ°Π½ΠΈΠ΅

ΠœΠ°Π³ΠΈΡ‡Π΅ΡΠΊΠΈΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹, Π·Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ __construct(), __destruct() ΠΈ __clone(), Π’Π Π•Π‘Π£Π•Π’Π‘Π― ΠΎΠ±ΡŠΡΠ²Π»ΡΡ‚ΡŒ с ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠΌ public, ΠΈΠ½Π°Ρ‡Π΅ PHP выдаст ΠΎΡˆΠΈΠ±ΠΊΡƒ уровня E_WARNING. Π”ΠΎ PHP 8.0.0 для магичСских ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² __sleep(), __wakeup(), __serialize(), __unserialize() ΠΈ __set_state() Π½Π΅ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΠ»Π°ΡΡŒ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°.

Π’Π½ΠΈΠΌΠ°Π½ΠΈΠ΅

ΠŸΡ€ΠΈ объявлСнии Ρ‚ΠΈΠΏΠΎΠ² Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ магичСского ΠΌΠ΅Ρ‚ΠΎΠ΄Π° трСбуСтся ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΡΡ‚ΡŒ сигнатуру, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ описываСт этот Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚, ΠΈΠ½Π°Ρ‡Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ½Π΅Ρ‚ Ρ„Π°Ρ‚Π°Π»ΡŒΠ½Π°Ρ ошибка. Π”ΠΎ PHP 8.0.0 диагностичСскиС сообщСния Π½Π΅ ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΠ»ΠΈΡΡŒ. ΠŸΡ€ΠΈ этом Π² ΠΌΠ΅Ρ‚ΠΎΠ΄Π°Ρ… __construct() ΠΈ __destruct() Ρ‚ΠΈΠΏ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π° Π½Π΅ ΠΎΠ±ΡŠΡΠ²Π»ΡΡŽΡ‚, ΠΈΠ½Π°Ρ‡Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ½Π΅Ρ‚ Ρ„Π°Ρ‚Π°Π»ΡŒΠ½Π°Ρ ошибка.

ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹ __serialize() ΠΈ __unserialize()

public function __serialize(): array
public function __unserialize(array $data): void

Ѐункция serialize() провСряСт, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ Π»ΠΈ Π² классС магичСский ΠΌΠ΅Ρ‚ΠΎΠ΄ с Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ __serialize(). ΠœΠ΅Ρ‚ΠΎΠ΄, Ссли Π΅Π³ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ Π² классС, выполняСтся ΠΏΠ΅Ρ€Π΅Π΄ сСриализациСй. ЦСль ΠΌΠ΅Ρ‚ΠΎΠ΄Π° β€” Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ ассоциативный массив ΠΏΠ°Ρ€ Β«ΠΊΠ»ΡŽΡ‡ β€” Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅Β» для прСдставлСния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π² сСриализованной Ρ„ΠΎΡ€ΠΌΠ΅. ΠŸΡ€ΠΈ Π½Π΅Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π΅ массива выбрасываСтся ошибка TypeError.

Π—Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅:

ΠŸΡ€ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ Π² классС ΠΎΠ±ΠΎΠΈΡ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² β€” ΠΈ __serialize(), ΠΈ __sleep(), PHP Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄ __serialize(). ΠœΠ΅Ρ‚ΠΎΠ΄ __sleep() проигнорируСтся. PHP ΠΏΡ€ΠΎΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΠ΅Ρ‚ интСрфСйсный ΠΌΠ΅Ρ‚ΠΎΠ΄ serialize(), ΠΈ вмСсто Π½Π΅Π³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ __serialize(), Ссли класс Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ интСрфСйс Serializable.

НазначСниС ΠΌΠ΅Ρ‚ΠΎΠ΄Π° __serialize() Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ ΡƒΠ΄ΠΎΠ±Π½ΠΎΠ³ΠΎ для сСриализации ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½ΠΎΠ³ΠΎ прСдставлСния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. Π­Π»Π΅ΠΌΠ΅Π½Ρ‚Π°ΠΌ массива Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ΡΡ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ свойствам ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Π½ΠΎ это Π½Π΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ.

И Π½Π°ΠΎΠ±ΠΎΡ€ΠΎΡ‚, функция unserialize() провСряСт Π΄ΠΎΡΡ‚ΡƒΠΏΠ½ΠΎΡΡ‚ΡŒ магичСского ΠΌΠ΅Ρ‚ΠΎΠ΄Π° __unserialize(). PHP пСрСдаст ΠΌΠ΅Ρ‚ΠΎΠ΄Ρƒ массив, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ восстановил ΠΈ Π²Π΅Ρ€Π½ΡƒΠ» ΠΌΠ΅Ρ‚ΠΎΠ΄ __serialize(), Ссли ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ Π² классС. А Π·Π°Ρ‚Π΅ΠΌ, Ссли потрСбуСтся, ΠΌΠ΅Ρ‚ΠΎΠ΄ восстановит свойства ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈΠ· этого массива.

Π—Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅:

ΠŸΡ€ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ Π² классС ΠΎΠ±ΠΎΠΈΡ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² β€” ΠΈ __unserialize(), ΠΈ __wakeup(), PHP Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄ __unserialize(), Π° ΠΌΠ΅Ρ‚ΠΎΠ΄ __wakeup() проигнорируСтся.

Π—Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅:

ΠœΠ΅Ρ‚ΠΎΠ΄ доступСн с PHP 7.4.0.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ #1 ΠŸΡ€ΠΈΠΌΠ΅Ρ€ сСриализации ΠΈ дСсСриализации

<?php

class Connection
{
protected
$link;
private
$dsn, $username, $password;

public function
__construct($dsn, $username, $password)
{
$this->dsn = $dsn;
$this->username = $username;
$this->password = $password;
$this->connect();
}

private function
connect()
{
$this->link = new PDO($this->dsn, $this->username, $this->password);
}

public function
__serialize(): array
{
return [
'dsn' => $this->dsn,
'user' => $this->username,
'pass' => $this->password,
];
}

public function
__unserialize(array $data): void
{
$this->dsn = $data['dsn'];
$this->username = $data['user'];
$this->password = $data['pass'];

$this->connect();
}
}

?>

ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹ __sleep() ΠΈ __wakeup()

public function __sleep(): array
public function __wakeup(): void

Ѐункция serialize() провСряСт, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ Π»ΠΈ Π² классС магичСский ΠΌΠ΅Ρ‚ΠΎΠ΄ с Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ __sleep(). ΠœΠ°Π³ΠΈΡ‡Π΅ΡΠΊΠΈΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄, Ссли Π΅Π³ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ, выполняСтся ΠΏΠ΅Ρ€Π΅Π΄ сСриализациСй. Π’ ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅ ΠΎΡ‡ΠΈΡ‰Π°ΡŽΡ‚ сСриализуСмый ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, Ссли трСбуСтся, ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ ΠΈΠ· ΠΌΠ΅Ρ‚ΠΎΠ΄Π° массив с названиями ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ трСбуСтся ΡΠ΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ. ΠŸΡ€ΠΈ Π½Π΅Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π΅ ΠΈΠ· магичСского ΠΌΠ΅Ρ‚ΠΎΠ΄Π° значСния сСриализуСтся константа null ΠΈ выдаётся ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ E_NOTICE.

Π—Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅:

ΠœΠ΅Ρ‚ΠΎΠ΄Ρƒ __sleep() нСльзя Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ названия Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹Ρ… свойств Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΡ… классов. Π­Ρ‚ΠΎ сгСнСрируСт ΠΎΡˆΠΈΠ±ΠΊΡƒ уровня E_NOTICE. Для сСриализации Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹Ρ… Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΡ… свойств вмСсто магичСского ΠΌΠ΅Ρ‚ΠΎΠ΄Π° __sleep Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ магичСский ΠΌΠ΅Ρ‚ΠΎΠ΄ __serialize().

Π—Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅:

Начиная с PHP 8.0.0 ΠΏΡ€ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π΅ ΠΈΠ· ΠΌΠ΅Ρ‚ΠΎΠ΄Π° __sleep() значСния ΠΊΡ€ΠΎΠΌΠ΅ массива гСнСрируСтся ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅. РаньшС Π²Ρ‹Π΄Π°Π²Π°Π»ΠΎΡΡŒ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅.

НазначСниС ΠΌΠ΅Ρ‚ΠΎΠ΄Π° __sleep() β€” Π·Π°Ρ„ΠΈΠΊΡΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ»ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Ρ‹Π΅ Π·Π°Π΄Π°Ρ‡ΠΈ очистки. ΠœΠ΅Ρ‚ΠΎΠ΄ Ρ‚Π°ΠΊΠΆΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ΠΌ, ΠΊΠΎΠ³Π΄Π° трСбуСтся ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Π°ΡΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.

И Π½Π°ΠΎΠ±ΠΎΡ€ΠΎΡ‚, функция unserialize() провСряСт Π² классС ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ магичСского ΠΌΠ΅Ρ‚ΠΎΠ΄Π° с Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ __wakeup(). ΠœΠ΅Ρ‚ΠΎΠ΄Ρƒ пробуТдСния, Ссли Π΅Π³ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ Π² классС, доступно восстановлСниС Π»ΡŽΠ±Ρ‹Ρ… рСсурсов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ΡΡ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ.

НазначСниС ΠΌΠ΅Ρ‚ΠΎΠ΄Π° __wakeup() β€” Π²ΠΎΡΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ соСдинСния с Π±Π°Π·ΠΎΠΉ Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΡ‚Π΅Ρ€ΡΠ»ΠΈΡΡŒ ΠΏΡ€ΠΈ сСриализации, ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Π·Π°Π΄Π°Ρ‡ΠΈ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠΉ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ #2 ΠŸΡ€ΠΈΠΌΠ΅Ρ€ засыпания ΠΈ пробуТдСния

<?php

class Connection
{
protected
$link;
private
$dsn, $username, $password;

public function
__construct($dsn, $username, $password)
{
$this->dsn = $dsn;
$this->username = $username;
$this->password = $password;
$this->connect();
}

private function
connect()
{
$this->link = new PDO($this->dsn, $this->username, $this->password);
}

public function
__sleep()
{
return array(
'dsn', 'username', 'password');
}

public function
__wakeup()
{
$this->connect();
}
}

?>

ΠœΠ΅Ρ‚ΠΎΠ΄ __toString()

public function __toString(): string

ΠœΠ΅Ρ‚ΠΎΠ΄ __toString() Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ классу Π²Ρ‹Π±ΠΈΡ€Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊ класс Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π΅Π°Π³ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, ΠΊΠΎΠ³Π΄Π° с Π½ΠΈΠΌ ΠΎΠ±Ρ€Π°Ρ‰Π°ΡŽΡ‚ΡΡ ΠΊΠ°ΠΊ со строкой. НапримСр, класс Ρ€Π΅ΡˆΠ°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π²Ρ‹Π²Π΅Π΄Π΅Ρ‚ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ echo $obj;.

Π’Π½ΠΈΠΌΠ°Π½ΠΈΠ΅

Π‘ PHP 8.0.0 Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ соотвСтствуСт стандартной сСмантикС PHP-Ρ‚ΠΈΠΏΠΎΠ², поэтому Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ приводится ΠΊ строкС (string), Ссли Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΈ Ссли ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΠ»ΠΈ ΡΡ‚Ρ€ΠΎΠ³ΡƒΡŽ Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΡŽ.

ΠžΠ±ΡŠΠ΅ΠΊΡ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ интСрфСйс Stringable, Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒΡΡ объявлСниСм Ρ‚ΠΈΠΏΠ° string, Ссли Π²ΠΊΠ»ΡŽΡ‡ΠΈΠ»ΠΈ ΡΡ‚Ρ€ΠΎΠ³ΡƒΡŽ Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΡŽ. ОбъявлСниС Ρ‚ΠΈΠΏΠ° Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ интСрфСйс Stringable ΠΈ строку (string) Ρ‡Π΅Ρ€Π΅Π· объСдинСниС Ρ‚ΠΈΠΏΠΎΠ², Ссли трСбуСтся Ρ‚Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅.

Π‘ PHP 8.0.0 ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ класс, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ описали магичСский ΠΌΠ΅Ρ‚ΠΎΠ΄ __toString(), нСявно Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ интСрфСйс Stringable, ΠΈ поэтому ΠΏΡ€ΠΎΡ…ΠΎΠ΄ΠΈΡ‚ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Ρ‚ΠΈΠΏΠ° для этого интСрфСйса. Π’ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ класса Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΡŽΡ‚ явно ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ класс Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ интСрфСйс.

Π’ PHP 7.4 Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π° Π”ΠžΠ›Π–ΠΠž ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ‚ΡŒ Ρ‚ΠΈΠΏΡƒ string, ΠΈΠ½Π°Ρ‡Π΅ выбрасываСтся ошибка Error.

Π”ΠΎ PHP 7.4.0 Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π° Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ‚ΡŒ Ρ‚ΠΈΠΏΡƒ string, ΠΈΠ½Π°Ρ‡Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π»Π° Ρ„Π°Ρ‚Π°Π»ΡŒΠ½Π°Ρ ошибка уровня E_RECOVERABLE_ERROR.

Π’Π½ΠΈΠΌΠ°Π½ΠΈΠ΅

Π”ΠΎ PHP 7.4.0 Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π»Π° Ρ„Π°Ρ‚Π°Π»ΡŒΠ½Π°Ρ ошибка, Ссли ΠΈΠ· ΠΌΠ΅Ρ‚ΠΎΠ΄Π° __toString() выбрасывали ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ #3 ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€

<?php

// ОбъявлСниС простого класса
class TestClass
{
public
$foo;

public function
__construct($foo)
{
$this->foo = $foo;
}

public function
__toString()
{
return
$this->foo;
}
}

$class = new TestClass('ΠŸΡ€ΠΈΠ²Π΅Ρ‚');
echo
$class;

?>

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Π½Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°:

ΠŸΡ€ΠΈΠ²Π΅Ρ‚

ΠœΠ΅Ρ‚ΠΎΠ΄ __invoke()

function __invoke( ...$values): mixed

ΠœΠ΅Ρ‚ΠΎΠ΄ __invoke() вызываСтся, ΠΊΠΎΠ³Π΄Π° скрипт пытаСтся Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΊΠ°ΠΊ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ #4 ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π²Ρ‹Π·ΠΎΠ²Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° класса с ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ __invoke()

<?php

class CallableClass
{
public function
__invoke($x)
{
var_dump($x);
}
}

$obj = new CallableClass();

$obj(5);
var_dump(is_callable($obj));

?>

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Π½Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°:

int(5)
bool(true)

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ #5 ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π²Ρ‹Π·ΠΎΠ²Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° класса с ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ __invoke()

<?php

class Sort
{
private
$key;

public function
__construct(string $key)
{
$this->key = $key;
}

public function
__invoke(array $a, array $b): int
{
return
$a[$this->key] <=> $b[$this->key];
}
}

$customers = [
[
'id' => 1, 'first_name' => 'John', 'last_name' => 'Do'],
[
'id' => 3, 'first_name' => 'Alice', 'last_name' => 'Gustav'],
[
'id' => 2, 'first_name' => 'Bob', 'last_name' => 'Filipe']
];

// Π‘ΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²ΠΊΠ° ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ
usort($customers, new Sort('first_name'));
print_r($customers);

// Π‘ΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²ΠΊΠ° ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² ΠΏΠΎ Ρ„Π°ΠΌΠΈΠ»ΠΈΠΈ
usort($customers, new Sort('last_name'));
print_r($customers);

?>

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Π½Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°:

Array
(
    [0] => Array
        (
            [id] => 3
            [first_name] => Alice
            [last_name] => Gustav
        )

    [1] => Array
        (
            [id] => 2
            [first_name] => Bob
            [last_name] => Filipe
        )

    [2] => Array
        (
            [id] => 1
            [first_name] => John
            [last_name] => Do
        )

)
Array
(
    [0] => Array
        (
            [id] => 1
            [first_name] => John
            [last_name] => Do
        )

    [1] => Array
        (
            [id] => 2
            [first_name] => Bob
            [last_name] => Filipe
        )

    [2] => Array
        (
            [id] => 3
            [first_name] => Alice
            [last_name] => Gustav
        )

)

ΠœΠ΅Ρ‚ΠΎΠ΄ __set_state()

static function __set_state(array $properties): object

Π­Ρ‚ΠΎΡ‚ статичСский ΠΌΠ΅Ρ‚ΠΎΠ΄ вызываСтся для Ρ‚Π΅Ρ… классов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡΠΊΡΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ΡΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ var_export().

ЕдинствСнный ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° β€” массив, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ содСрТит экспортируСмыС свойства Π² Π²ΠΈΠ΄Π΅ ['property' => value, ...].

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ #6 ΠŸΡ€ΠΈΠΌΠ΅Ρ€ использования ΠΌΠ΅Ρ‚ΠΎΠ΄Π° __set_state()

<?php

class A
{
public
$var1;
public
$var2;

public static function
__set_state($an_array)
{
$obj = new A;
$obj->var1 = $an_array['var1'];
$obj->var2 = $an_array['var2'];
return
$obj;
}
}

$a = new A();
$a->var1 = 5;
$a->var2 = 'foo';

$b = var_export($a, true);
var_dump($b);
eval(
'$c = ' . $b . ';');
var_dump($c);

?>

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Π½Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°:

string(60) "A::__set_state(array(
   'var1' => 5,
   'var2' => 'foo',
))"
object(A)#2 (2) {
  ["var1"]=>
  int(5)
  ["var2"]=>
  string(3) "foo"
}

Π—Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅: ΠŸΡ€ΠΈ экспортС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° функция var_export() Π½Π΅ провСряСт, Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ Π»ΠΈ класс ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΌΠ΅Ρ‚ΠΎΠ΄ __set_state(), поэтому ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½Ρ‹ΠΉ ΠΈΠΌΠΏΠΎΡ€Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² выбросит ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Error, Ссли ΠΌΠ΅Ρ‚ΠΎΠ΄ __set_state() Π½Π΅ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π»ΠΈ. Π’ частности, это относится ΠΊ ряду Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΡ… классов. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡΡ‚ нСсёт ΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²Π΅Π½Π½ΠΎΡΡ‚ΡŒ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½Ρ‹ΠΉ ΠΈΠΌΠΏΠΎΡ€Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π΅Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², класс ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ __set_state().

ΠœΠ΅Ρ‚ΠΎΠ΄ __debugInfo()

function __debugInfo(): array

Π­Ρ‚ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ вызываСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ var_dump(), ΠΊΠΎΠ³Π΄Π° трСбуСтся вывСсти список свойств ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. Ѐункция Π²Ρ‹Π²Π΅Π΄Π΅Ρ‚ ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π½ΠΎΠ΅ свойство c ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π°ΠΌΠΈ public, protected ΠΈ private, Ссли ΠΌΠ΅Ρ‚ΠΎΠ΄ Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ #7 ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π²Ρ‹Π²ΠΎΠ΄Π° ΠΎΡ‚Π»Π°Π΄ΠΎΡ‡Π½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ __debugInfo()

<?php

class C
{
private
$prop;

public function
__construct($val)
{
$this->prop = $val;
}

public function
__debugInfo()
{
return [
'propSquared' => $this->prop ** 2,
];
}
}

var_dump(new C(42));

?>

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Π½Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°:

object(C)#1 (1) {
  ["propSquared"]=>
  int(1764)
}
οΌ‹Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ

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

up
53
jon at webignition dot net ΒΆ
17 years ago
The __toString() method is extremely useful for converting class attribute names and values into common string representations of data (of which there are many choices). I mention this as previous references to __toString() refer only to debugging uses.

I have previously used the __toString() method in the following ways:

 - representing a data-holding object as:
   - XML
   - raw POST data
   - a GET query string
   - header name:value pairs

 - representing a custom mail object as an actual email (headers then body, all correctly represented)

When creating a class, consider what possible standard string representations are available and, of those, which would be the most relevant with respect to the purpose of the class.

Being able to represent data-holding objects in standardised string forms makes it much easier for your internal representations of data to be shared in an interoperable way with other applications.
up
6
tyler at nighthound dot us ΒΆ
2 years ago
Please note that as of PHP 8.2 implementing __serialize() has no control over the output of json_encode(). you still have to implement JsonSerializable.
up
15
jsnell at e-normous dot com ΒΆ
17 years ago
Be very careful to define __set_state() in classes which inherit from a parent using it, as the static __set_state() call will be called for any children.  If you are not careful, you will end up with an object of the wrong type.  Here is an example:

<?php
class A
{
    public $var1; 

    public static function __set_state($an_array)
    {
        $obj = new A;
        $obj->var1 = $an_array['var1'];  
        return $obj;
    }
}

class B extends A {
}

$b = new B;
$b->var1 = 5;

eval('$new_b = ' . var_export($b, true) . ';'); 
var_dump($new_b);
/*
object(A)#2 (1) {
  ["var1"]=>
  int(5)
}
*/
?>
up
8
martin dot goldinger at netserver dot ch ΒΆ
20 years ago
When you use sessions, its very important to keep the sessiondata small, due to low performance with unserialize. Every class shoud extend from this class. The result will be, that no null Values are written to the sessiondata. It will increase performance.

<?
class BaseObject
{
    function __sleep()
    {
        $vars = (array)$this;
        foreach ($vars as $key => $val)
        {
            if (is_null($val))
            {
                unset($vars[$key]);
            }
        }    
        return array_keys($vars);
    }
};
?>
up
9
kguest at php dot net ΒΆ
9 years ago
__debugInfo  is also utilised when calling print_r on an object:

$ cat test.php
<?php
class FooQ {

     private $bar = '';

     public function __construct($val) {

         $this->bar = $val;
     }

     public function __debugInfo()
     {
         return ['_bar' => $this->bar];
     }
}
$fooq = new FooQ("q");
print_r ($fooq);

$ php test.php
FooQ Object
(
    [_bar] => q
)
$
up
5
daniel dot peder at gmail dot com ΒΆ
8 years ago
http://sandbox.onlinephpfunctions.com/code/4d2cc3648aed58c0dad90c7868173a4775e5ba0c

IMHO a bug or need feature change

providing a object as a array index doesn't try to us __toString() method so some volatile object identifier is used to index the array, which is breaking any persistency. Type hinting solves that, but while other than "string" type hinting doesn't work on ob jects, the automatic conversion to string should be very intuitive.

PS: tried to submit bug, but withot patch the bugs are ignored, unfortunately, I don't C coding

<?php

class shop_product_id {
    
    protected $shop_name;
    protected $product_id;
    
    function __construct($shop_name,$product_id){
        $this->shop_name = $shop_name;
        $this->product_id = $product_id;
    }

    function __toString(){
        return $this->shop_name . ':' . $this->product_id;
    }
}

$shop_name = 'Shop_A';
$product_id = 123;
$demo_id = $shop_name . ':' . $product_id;
$demo_name = 'Some product in shop A';

$all_products = [ $demo_id => $demo_name ];
$pid = new shop_product_id( $shop_name, $product_id );

echo "with type hinting: ";
echo ($demo_name === $all_products[(string)$pid]) ? "ok" : "fail";
echo "\n";

echo "without type hinting: ";
echo ($demo_name === $all_products[$pid]) ?  "ok" : "fail";
echo "\n";
up
4
ctamayo at sitecrafting dot com ΒΆ
5 years ago
Due to a bug in PHP <= 7.3, overriding the __debugInfo() method from SPL classes is silently ignored.

<?php

class Debuggable extends ArrayObject {
  public function __debugInfo() {
    return ['special' => 'This should show up'];
  }
}

var_dump(new Debuggable());

// Expected output:
// object(Debuggable)#1 (1) {
//   ["special"]=>
//   string(19) "This should show up"
// }

// Actual output:
// object(Debuggable)#1 (1) {
//   ["storage":"ArrayObject":private]=>
//   array(0) {
//   }
// }

?>

Bug report: https://bugs.php.net/bug.php?id=69264
up
6
ddavenport at newagedigital dot com ΒΆ
21 years ago
One of the principles of OOP is encapsulation--the idea that an object should handle its own data and no others'.  Asking base classes to take care of subclasses' data, esp considering that a class can't possibly know how many dozens of ways it will be extended, is irresponsible and dangerous.

Consider the following...

<?php
class SomeStupidStorageClass
{
  public function getContents($pos, $len) { ...stuff... }
}

class CryptedStorageClass extends SomeStupidStorageClass
{
  private $decrypted_block;
  public function getContents($pos, $len) { ...decrypt... }
}
?>

If SomeStupidStorageClass decided to serialize its subclasses' data as well as its own, a portion of what was once an encrypted thingie could be stored, in the clear, wherever the thingie was stored.  Obviously, CryptedStorageClass would never have chosen this...but it had to either know how to serialize its parent class's data without calling parent::_sleep(), or let the base class do what it wanted to.

Considering encapsulation again, no class should have to know how the parent handles its own private data.  And it certainly shouldn't have to worry that users will find a way to break access controls in the name of convenience.

If a class wants both to have private/protected data and to survive serialization, it should have its own __sleep() method which asks the parent to report its own fields and then adds to the list if applicable.  Like so....

<?php

class BetterClass
{
  private $content;

  public function __sleep()
  {
    return array('basedata1', 'basedata2');
  }

  public function getContents() { ...stuff... }
}

class BetterDerivedClass extends BetterClass
{
  private $decrypted_block;

  public function __sleep()
  {
    return parent::__sleep();
  }

  public function getContents() { ...decrypt... }
}

?>

The derived class has better control over its data, and we don't have to worry about something being stored that shouldn't be.
up
4
rayRO ΒΆ
20 years ago
If you use the Magical Method '__set()', be shure that the call of
<?php
$myobject->test['myarray'] = 'data';
?>
will not appear!

For that u have to do it the fine way if you want to use __set Method ;)
<?php
$myobject->test = array('myarray' => 'data');
?>

If a Variable is already set, the __set Magic Method already wont appear!

My first solution was to use a Caller Class.
With that, i ever knew which Module i currently use!
But who needs it... :]
There are quiet better solutions for this...
Here's the Code:

<?php
class Caller {
    public $caller;
    public $module;

    function __call($funcname, $args = array()) {
        $this->setModuleInformation();

        if (is_object($this->caller) && function_exists('call_user_func_array'))
            $return = call_user_func_array(array(&$this->caller, $funcname), $args);
        else
            trigger_error("Call to Function with call_user_func_array failed", E_USER_ERROR);
        
        $this->unsetModuleInformation();
        return $return;
    }

    function __construct($callerClassName = false, $callerModuleName = 'Webboard') {
        if ($callerClassName == false)
            trigger_error('No Classname', E_USER_ERROR);

        $this->module = $callerModuleName;

        if (class_exists($callerClassName))
            $this->caller = new $callerClassName();
        else
            trigger_error('Class not exists: \''.$callerClassName.'\'', E_USER_ERROR);

        if (is_object($this->caller))
        {
            $this->setModuleInformation();
            if (method_exists($this->caller, '__init'))
                $this->caller->__init();
            $this->unsetModuleInformation();
        }
        else
            trigger_error('Caller is no object!', E_USER_ERROR);
    }

    function __destruct() {
        $this->setModuleInformation();
        if (method_exists($this->caller, '__deinit'))
            $this->caller->__deinit();
        $this->unsetModuleInformation();
    }

    function __isset($isset) {
        $this->setModuleInformation();
        if (is_object($this->caller))
            $return = isset($this->caller->{$isset});
        else
            trigger_error('Caller is no object!', E_USER_ERROR);
        $this->unsetModuleInformation();
        return $return;
    }

    function __unset($unset) {
        $this->setModuleInformation();
        if (is_object($this->caller)) {
            if (isset($this->caller->{$unset}))
                unset($this->caller->{$unset});
        }
        else
            trigger_error('Caller is no object!', E_USER_ERROR);
        $this->unsetModuleInformation();
    }

    function __set($set, $val) {
        $this->setModuleInformation();
        if (is_object($this->caller))
            $this->caller->{$set} = $val;
        else
            trigger_error('Caller is no object!', E_USER_ERROR);
        $this->unsetModuleInformation();
    }

    function __get($get) {
        $this->setModuleInformation();
        if (is_object($this->caller)) {
            if (isset($this->caller->{$get}))
                $return = $this->caller->{$get};
            else
                $return = false;
        }
        else
            trigger_error('Caller is no object!', E_USER_ERROR);
        $this->unsetModuleInformation();
        return $return;
    }
    
    function setModuleInformation() {
        $this->caller->module = $this->module;
    }

    function unsetModuleInformation() {
        $this->caller->module = NULL;
    }
}

// Well this can be a Config Class?
class Config {
    public $module;

    public $test;

    function __construct()
    {
        print('Constructor will have no Module Information... Use __init() instead!<br />');
        print('--> '.print_r($this->module, 1).' <--');
        print('<br />');
        print('<br />');
        $this->test = '123';
    }
    
    function __init()
    {
        print('Using of __init()!<br />');
        print('--> '.print_r($this->module, 1).' <--');
        print('<br />');
        print('<br />');
    }
    
    function testFunction($test = false)
    {
        if ($test != false)
            $this->test = $test;
    }
}

echo('<pre>');
$wow = new Caller('Config', 'Guestbook');
print_r($wow->test);
print('<br />');
print('<br />');
$wow->test = '456';
print_r($wow->test);
print('<br />');
print('<br />');
$wow->testFunction('789');
print_r($wow->test);
print('<br />');
print('<br />');
print_r($wow->module);
echo('</pre>');
?>

Outputs something Like:

Constructor will have no Module Information... Use __init() instead!
-->  <--

Using of __init()!
--> Guestbook <--

123

456

789

Guestbook
up
3
jeffxlevy at gmail dot com ΒΆ
20 years ago
Intriguing what happens when __sleep() and __wakeup() and sessions() are mixed. I had a hunch that, as session data is serialized, __sleep would be called when an object, or whatever, is stored in _SESSION. true. The same hunch applied when session_start() was called. Would __wakeup() be called? True. Very helpful, specifically as I'm building massive objects (well, lots of simple objects stored in sessions), and need lots of automated tasks (potentially) reloaded at "wakeup" time. (for instance, restarting a database session/connection).