php魔术方法
在php类保留方法中以 “__”两个下划线开头的函数称为魔术方法,我的理解为php类设计中自定义好的函数。
常见的魔术方法有:
__construct(),类的构造函数
__destruct(),类的析构函数
__call(),在对象中调用一个不可访问方法时调用
__callStatic(),用静态方式中调用一个不可访问方法时调用
__get(),获得一个类的成员变量时调用
__set(),设置一个类的成员变量时调用
__isset(),当对不可访问属性调用isset()或empty()时调用
__unset(),当对不可访问属性调用unset()时被调用
__sleep(),执行serialize()时,先会调用这个函数
__wakeup(),执行unserialize()时,先会调用这个函数
__toString(),类被当成字符串时的回应方法
__invoke(),调用函数的方式调用一个对象时的回应方法
__set_state(),调用var_export()导出类时,此静态方法会被调用
__clone(),当对象复制完成时调用
__autoload(),尝试加载未定义的类
__debugInfo(),打印所需调试信息
__construct()与__destruct()
__construct() 构造函数与 __destruct() 析构函数,与其他的语言如java,c#,一样,构造函数就是在对象实例化的时候先执行初始化的方法。
__construct()构造函数只有在new 一个对象的时候会触发,在serialize 序列化和unserialize反序列化中都不会触发
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<?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 ); ?> |
输出结果
__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 ( "0000" . "<br>" ); $a =serialize( $f ); echo ( "1111" . "<br>" ); unset( $f ); echo ( "2222" . "<br>" ); unserialize( $a ); ?> |
输出结果
__call
__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 函数被调用" ); } //当调用不存在的方法时,方法名作为参数传到$name 变量,方法名的输入参数传到arguments参数列表中 public function __call( $name , $arguments ) { // TODO: Implement __call() method. echo ( $name . "---" . $arguments [0]); } } $f = new demo1(); $f ->f2( "123" ); //调用不存在的方法f2() ?> |
输出结果
__get
__get() 魔术方法是当访问一个对象不存在的变量时就会被触发
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<?php class demo1{ private $k1 ; public function f1(){ echo ( "f1 函数被调用" ); } public function __get( $name ) //不存在的变量k会以参数传到$name { echo ( $name ); } } $f = new demo1(); $f ->k; //不存在的变量k ?> |
输出结果
__set
__set() 魔术方法是当给一个对象不存在的变量赋值时就会被触发
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 __set( $name , $value ) { echo ( $name . "---" . $value ); } } $f = new demo1(); $f ->k=123; //给不存在的成员变量赋值 ?> |
输出结果
__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); //使用isset方法判断私有成员属性k1 empty ( $f2 ->k1); //使用empty方法判断私有成员属性k1 ?> |
输出结果
__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 $k1 ; public function f1(){ echo ( "f1 函数被调用" ); } public function __unset( $name ) { echo ( $name ); } } $f = new demo1(); $f2 =unserialize(serialize( $f )); //反序列化 unset( $f2 ->k1); //使用unset销毁私有成员属性k1 unset( $f2 ->faaa); //使用unset销毁不存在的成员属性faaa ?> |
输出结果
__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 ); ?> |
输出结果
__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 ); ?> |
输出结果
__toString
如果一个对象类中存在__toString魔术方法,这个对象类被当做字符串进行处理时,就会触发__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 ); ?> |
输出结果
__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 (); ?> |
输出结果
原文链接:https://blog.csdn.net/qq_42077227/article/details/127540351
暂无评论内容