魔术方法是PHP面向对象中特有的特性。它们在特定的情况下被触发,都是以双下划线开头,你可以把它们理解为钩子,利用模式方法可以轻松实现PHP面向对象中重载(Overloading即动态创建类属性和方法)。魔术方法很多还是成对出现的,以下列出目前PHP中所有的模式方法。
1.__construct,__destruct
__constuct构建对象的时被调用;
__destruct明确销毁对象或脚本结束时被调用;
2.__get,__set
__set当给不可访问或不存在属性赋值时被调用
__get读取不可访问或不存在属性时被调用
3.__isset,__unset
__isset对不可访问或不存在的属性调用isset()或empty()时被调用
__unset对不可访问或不存在的属性进行unset时被调用
4.__call,__callStatic
__call调用不可访问或不存在的方法时被调用
__callStatic调用不可访问或不存在的静态方法时被调用
5.__sleep,__wakeup
__sleep当使用serialize时被调用,当你不需要保存大对象的所有数据时很有用
__wakeup当使用unserialize时被调用,可用于做些对象的初始化操作
6.__clone
进行对象clone时被调用,用来调整对象的克隆行为
7.__toString
当一个类被转换成字符串时被调用
8.__invoke
当以函数方式调用对象时被调用
9.__set_state
当调用var_export()导出类时,此静态方法被调用。用__set_state的返回值做为var_export的返回值。
10.__debuginfo
当调用var_dump()打印对象时被调用(当你不想打印所有属性)适用于PHP5.6版本
PHP魔术方法使用实例如下:
1 <?php 2 3 class Magic 4 { 5 public $var = 'test'; 6 7 //构造函数,在创建对象的时候调用 8 public function __construct() 9 { 10 echo '__construct called'.PHP_EOL; 11 } 12 13 //某个对象的引用都被删除、对象被销毁、调用exit()后、脚本关闭时被调用 14 public function __destruct() 15 { 16 echo '__destruct called'.PHP_EOL; 17 } 18 19 //当给不可访问或不存在属性赋值时被调用 20 public function __set($name, $value) 21 { 22 echo $name.'-'.$value; 23 echo '__set called'.PHP_EOL; 24 } 25 26 //读取不可访问或不存在属性时被调用 27 public function __get($name) 28 { 29 echo $name; 30 echo '__get called'.PHP_EOL; 31 } 32 33 //调用不可访问或不存在的方法时被调用 34 public function __call($name, $arguments) 35 { 36 echo $name . '-' . implode(',', $arguments); 37 echo '__call called'.PHP_EOL; 38 } 39 40 //调用不可访问或不存在的静态方法时被调用 41 public static function __callStatic($name, $arguments) 42 { 43 echo $name . '-' . implode(',', $arguments); 44 echo '__callStatic called'.PHP_EOL; 45 } 46 47 //对不可访问或不存在的属性调用isset()或empty()时被调用 48 public function __isset($name) 49 { 50 echo $name; 51 echo '__isset called'.PHP_EOL; 52 return true; 53 } 54 55 //对不可访问或不存在的属性进行unset时被调用 56 public function __unset($name) 57 { 58 echo $name; 59 echo '__unset called'.PHP_EOL; 60 } 61 62 //serialize时被调用,当你不需要保存大对象的所有数据时很有用 63 public function __sleep() 64 { 65 echo '__sleep called'.PHP_EOL; 66 return array('var1111111111'); 67 } 68 69 //unserialize时被调用,可用于做些对象的初始化操作 70 public function __wakeup() 71 { 72 echo '__wakeup called'.PHP_EOL; 73 $this->var = 'test after wakeup'; 74 } 75 76 //当一个类被转换成字符串时被调用 77 public function __toString() 78 { 79 return '__toString called'.PHP_EOL; 80 } 81 82 //进行对象clone时被调用,用来调整对象的克隆行为 83 public function __clone() 84 { 85 echo '__clone called'.PHP_EOL; 86 } 87 88 //当以函数方式调用对象时被调用 89 public function __invoke() 90 { 91 echo '__invoke called'.PHP_EOL; 92 } 93 94 //当调用var_export()导出类时,此静态方法被调用。用__set_state的返回值做为var_export的返回值。 95 public static function __set_state($arr) 96 { 97 return '__set_state called'.PHP_EOL; 98 } 99 100 //当调用var_dump()打印对象时被调用(当你不想打印所有属性)适用于PHP5.6版本 101 public function __debuginfo($arr) 102 { 103 echo '__debuginfo called'.PHP_EOL; 104 return array( 105 'var' => 'test fro __debuginfo' 106 ); 107 } 108 } 109 110 $m = new Magic(); //__construct()被调用 111 $m->not_exist_property = test; //__set()被调用 112 echo $m->not_exist_property;//__get()被调用 113 $m->abc(1,2,3); //__call()被调用 114 echo isset($m->not_exist_property); //__isset()被调用,返回bool值 115 unset($m->not_exist_property); //__unset()被调用 116 echo $tmp = serialize($m); //__sleep()被调用 117 unserialize($tmp); //__wakeup()被调用 118 $m1 = clone $m; //__clone()被调用,对象默认是引用传递,使用clone关键词则可实现对象复制 119 $m(); //__invoke() 120 eval( '$m2 = ' . var_export ( $m , true ) . ';' );var_dump($m2); 121 var_dump($m); 122 //最后__destruct()被调用 123 124 /* 125 结果: 126 __construct called 127 not_exist_property-test__set called 128 not_exist_property__get called 129 abc-1,2,3__call called 130 not_exist_property__isset called 131 1not_exist_property__unset called 132 __sleep called 133 O:5:"Magic":1:{s:13:"var1111111111";N;}__wakeup called 134 __destruct called 135 __clone called 136 __invoke called 137 string(20) "__set_state called 138 " 139 class Magic#1 (1) { 140 public $var => 141 string(4) "test" 142 } 143 __destruct called 144 __destruct called 145 146 147 */