php反序列化
php魔术方法总结
1. 类的构造函数 __construct()
php对象创建后首先被调用的函数。在每一个类中都有一个构造函数,可以自定义。如果没有显示声明它,则会默认存在一个没有参数并且内容为空的构造方法。
- 触发:只有在new一个新的对象的时候会触发,在serialize 序列化和unserialize反序列化中都不会触发
1 2 3
| public function __construct(){ }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <?php class demo1{ private $k1; public function __construct() { echo("构造函数被调用"."<br>"); } public function f1(){ echo("f1 函数被调用"); } } echo("0000"."<br>"); $f=new demo1(); echo("1111"."<br>"); $a=serialize($f); echo("2222"."<br>"); unserialize($a); ?>
|
2. 析构函数 __destruct()
1 2 3
| public function __destrcut(){ echo("触发") }
|
- 触发:__destruct()在对象被销毁和serialize反序列化的情况下会被触发。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <?php class demo1{ private $k1; public function __destruct() { echo("析构函数被调用"."<br>"); } } $f=new demo1(); echo("Time_0"."<br>"); $a=serialize($f); echo("Time_1"."<br>"); unset($f); echo("Time_2"."<br>"); unserialize($a); ?>
|
3. __toString
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <?php header("Content-Type:text/html;charset=utf-8"); highlight_file(__FILE__); class demo1{ private $k1; public function f1(){ echo("f1 函数被调用"); } public function __toString() { echo("__toString 触发"); return ""; } } $f=new demo1(); echo($f); ?>
|
4. __call()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <?php class demo1{ private $k1; public function f1(){ echo("f1 函数被调用"); } public function __call($name, $arguments) { echo($name."---".$arguments[0]); } } $f=new demo1(); $f->f2("123"); ?>
|
1 2 3 4 5 6 7 8 9 10
| class song{ public $banana; public $abble; public function __toString()//对象当做字符串的时候,会触发__toString { if($this->abble == "abble"){ return $this->banana->ernb(); } } }
|
5. __get()
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <?php class demo1{ private $test; public function f1(){ echo("f1 函数被调用"); } public function __get($name)//不存在的变量test会以参数传到$name { echo($name); } } $f=new demo1(); $f->test1; ?>
|
1 2 3 4 5 6 7
| class rap{ public $text; public function __call($name, $arguments)//$test->bucunzai('123','456')调用一个不存在的方法时,会触发__call { return $this->text->aaabbb; } }
|
6. __set()
- 触发:__set()当给一个对象不存在的变量赋值时触发
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <?php highlight_file(__FILE__); class test{ private $test1; public function setTest1(){ echo "setTest1函数被调用<br>"; } public function __set($name,$value){ echo($name."---".$value); } } $foo = new test(); $foo->test=17; ?>
|
7. isset()
- 触发:当对不可访问属性调用isset()或empty()时会触发,例如访问类的私有属性,类不存在的成员属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <?php header("Content-Type:text/html;charset=utf-8"); highlight_file(__FILE__); class demo1{ private $k1; public function f1(){ echo("f1 函数被调用"); } public function __isset($name) { echo($name); } } $f=new demo1(); $f2=unserialize(serialize($f)); isset($f2->k1); empty($f2->k1); ?>
|
8. unset()
触发:当尝试使用unset() 销毁函数去销毁一个不可访问的成员属性时会触发,不可访问(包括私有成员属性,不存在的成员属性)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <?php header("Content-Type:text/html;charset=utf-8"); highlight_file(__FILE__); class demo1{ private $XU17; public function f1(){ echo("f1 函数被调用"); } public function __unset($name) { echo($name); } } $f=new demo1(); $f2=unserialize(serialize($f)); unset($f2->XU17); unset($f2->no_XU17); ?>
|
9. __sleep
- 触发:当对象被serialize 序列化时触发调用__sleep
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <?php header("Content-Type:text/html;charset=utf-8"); highlight_file(__FILE__); class demo1{ private $k1; public function f1(){ echo("f1 函数被调用"); } public function __sleep() { echo("在被序列化时被调用"); } } $f=new demo1(); echo("00000"."</br>"); serialize($f); ?>
|
10.__wakeup()
- 触发:当进行unserialize 反序列化对象时,
__wakeup
魔术方法会被触发,看起来__wakeup
与__sleep
触发条件是相反的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <?php header("Content-Type:text/html;charset=utf-8"); highlight_file(__FILE__); class demo1{ private $k1; public function f1(){ echo("f1 函数被调用"); } public function __wakeup() { echo("在被反序列化时被调用"); } } $f=new demo1(); $uz=serialize($f); echo("00000"."</br>"); unserialize($uz); ?>
|
11. __invoke()
- 触发:当一个对象类中存在
__invoke
魔术方法,这个对象类被当作函数进行调用时,就会触发__invoke
魔术方法,而不会产生错误
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <?php header("Content-Type:text/html;charset=utf-8"); highlight_file(__FILE__); class demo1{ private $k1; public function f1(){ echo("f1 函数被调用"); } public function __invoke() { echo("__invoke 被触发了"); } } $f=new demo1(); $f(); ?>
|
Rerference
[1] https://www.jb51.net/article/266562.htm