__sleep
,__wakeup
__sleep
在使用 serialize 方法進行序列化之前呼叫,返回需要進行序列化儲存的屬性陣列,如果屬性不在該陣列裡,儲存的是屬性的預設值,一般執行一些釋放清理比較大變數的工作。__wakeup
在使用 unserialize 方法進行反序列化後呼叫,一般是生成物件後執行初始化工作。
Test.php
<?php
class Test
{
public $a = 'A';
protected $b = 'I am B';
private $c = 'B';
public function __construct()
{
$this->a='I am A';
$this->b=520;
$this->c="I am C";
}
public function test()
{
echo "\ntest method\n";
echo $this->a;
echo $this->b;
echo $this->c;
}
public function __sleep()
{
return ['a','c'];
}
public function __wakeup()
{
$this->test();
}
}
$test = new Test();
echo "\nserialize\n";
$s = serialize($test);
var_export($s);
echo "\nunserialze\n";
$o = unserialize($s);
var_export($o);
執行結果
serialize
'O:4:"Test":2:{s:1:"a";s:6:"I am A";s:7:"' . "\0" . 'Test' . "\0" . 'c";s:6:"I am C";}'
unserialze
test method
I am AI am BI am CTest::__set_state(array(
'a' => 'I am A',
'b' => 'I am B',
'c' => 'I am C',
))
__serialize
,__unserialize
這兩個魔術方法 php7.4才支援,功能類似__sleep
和__wakeup
,不過__serialize
返回的是屬性的 key => value 陣列,__unserialize
需要手動解析資料__toString
把物件當字串列印時會執行該方法,並且需要返回一個字串
<?php
class Test
{
public $a = 'I am a string';
public function __toString()
{
return $this->a;
}
}
$o = new Test();
echo $o;
輸出結果:I am a string
__invoke
當將物件當方法來呼叫時會觸發該方法
<?php
class Test
{
public function __invoke($a, $b)
{
echo "Hello, I am from invoke\n";
echo "\n{$a}\n";
var_export(func_get_args());
}
}
$o = new Test();
$o("A","B", "C");
結果
Hello, I am from invoke
A
array (
0 => 'A',
1 => 'B',
2 => 'C',
)
__set_state
var_export 列印物件時會呼叫
<?php
class Test
{
public $a;
protected $b;
private $c;
public function __construct()
{
$this->a = 'AAA';
$this->b = 'BBB';
$this->c = 'CCC';
}
public function __set_state($data)
{
$o = new stdClass();
$o->d = $data['a'];
$o->e = $data['b'];
$o->c = $data['c'];
return $o;
}
}
$o = new Test();
$result = var_export($o, true);
eval('$tmp = ' . $result . ";");
var_export($tmp);
結果
stdClass::__set_state(array(
'd' => 'AAA',
'e' => 'BBB',
'c' => 'CCC',
))
__construct
例項化物件時執行構建函式__destruct
當物件引用被刪除時,執行解構函式__set
,__get
,__isset
,__unset
__set
當物件設定一個不可訪問屬性或者不存在的屬性名時,會觸發該函式__get
當物件獲取一個不可訪問屬性或不存在屬性值時,會觸發該函式__isset
判斷物件屬性是否存在,當屬性是不可訪問或不存在時會觸發__unset
釋放物件屬性,當屬性不可訪問或不存在時會觸發
<?php
class Test
{
public $a = 'AAA';
private $b = 'BBBB';
public function __set($key, $value)
{
echo "set {$key}={$value}\n";
$this->$key = $value;
}
public function __get($key)
{
echo "get {$key}=" . $this->$key;
}
public function __isset($name)
{
echo "trigger isset {$name}\n";
}
public function __unset($name)
{
echo "trigger unset {$name}\n";
}
}
$o = new Test();
$o->a="I am A\n";
$o->b="I am B\n";
$o->c="I am C\n";
echo $o->a . "\n";
echo $o->b . "\n";
echo $o->c . "\n";
echo $o->d . "\n";
var_export(isset($o->a));
echo "\n";
var_export(isset($o->b));
echo "\n";
var_export(isset($o->c));
echo "\n";
var_export(isset($a->d));
echo "\n";
unset($o->a);
unset($o->b);
unset($o->c);
unset($o->d);
結果
set b=I am B
set c=I am C
I am A
get b=I am B
I am C
PHP Notice: Undefined property: Test::$d in /Users/songzw/Downloads/require-include/call-static/set-get-test.php on line 16
get d=
true
trigger isset b
false
true
false
trigger unset b
trigger unset d
__call
,__callStatic
__call
當物件呼叫一個不存在的方法時會觸發該函式__callStatic
當類呼叫一個不存在的類方法時會觸發該函式
<?php
class Test
{
public function __call($method, $args)
{
echo "call method={$method},args=" . implode(',',$args) . "\n";
}
public static function __callStatic($method, $args)
{
echo "callStatic method={$method},args=" . implode(',',$args) . "\n";
}
}
$o = new Test();
$o->test1('aaa','bbb');
Test::testStatic1('ccccc','dddddd');
結果
call method=test1,args=aaa,bbb
callStatic method=testStatic1,args=ccccc,dddddd
__clone
當使用 clone 來複制物件時,會觸發該函式,可用於禁止拷貝物件或拷貝時修改屬性
本作品採用《CC 協議》,轉載必須註明作者和本文連結