php之魔术方法
指某些情况下,会自动调用的方法,称为魔术方法
php面向对象中,提供了这几个魔术方法,他们的特点都是以双划线__开头的,比如
__construct(),__destruct(),__call(),__callStatic(),__get(),__set(),__isset(),__unset(),__sleep(),__wakeup(),__toString(),__invoke(),__set_state(),__clone()等
1 <?php 2 /**** 3 魔术方法: 4 指某些情况下,会自动调用的方法,称为魔术方法 5 php面向对象中,提供了这几个魔术方法 6 他们的特点都是以双划线__开头的 7 __construct(),__destruct(),__call(),__callStatic(),__get(),__set(),__isset(),__unset(),__sleep(),__wakeup(),__toString(),__invoke(),__set_state(),__clone 8 ****/ 9 /*** 10 class Human{ 11 public $age = 29; 12 public function __clone(){ 13 echo '有人克隆我'; 14 } 15 } 16 $lisi = new Human(); 17 $zhangsan = clone $lisi; 18 print_r($zhangsan); 19 ***/ 20 21 22 23 /*** 24 class Human{ 25 private $money = '2333'; 26 protected $age = 22; 27 public $name = 'lily'; 28 } 29 $lily = new Human(); 30 echo $lily->name;//lily 31 //echo $lily->age;//权限报错 32 //echo $lily->sister;//unfined property 33 ***/ 34 35 class Human{ 36 private $money = '2333'; 37 protected $age = 22; 38 public $name = 'lily'; 39 public function __get($p){ 40 echo '你想访问我的',$p,'属性<br />'; 41 } 42 } 43 $lily = new Human(); 44 echo $lily->name,'<br />'; 45 echo $lily->age;//你想访问我的age属性 46 echo $lily->money;//你想访问我的money属性 47 echo $lily->friend;//你想访问我的friend属性 48 /*** 49 总结: 50 当我们调用一个权限上不允许的属性或不存在的属性时,__get()就会自动运行 51 并且会自动传一个参数,参数值是属性名(),而不是属性值,注意参数只能传一个,而且必须要写上 52 53 流程: 54 $lily->age---无权-->__get(age); 55 $lily->friend---没有此属性-->__get(friend); 56 相当于给人提供了一个接口,我们能自定义用户访问时的处理方法 57 ***/ 58 echo $lily->aaa = 111; 59 echo $lily->bbb = 222; 60 print_r($lily); 61 /*** 62 其实,对象就是一个属性集,在js中更明显, 63 如果这么随便就能添加属性,导致这个对象属性过多,不好管理 64 ***/ 65 class Stu{ 66 private $money = 2333; 67 protected $age = 23; 68 public $name = 'hmm'; 69 public function __set($a,$b){ 70 echo '你想设置我的',$a,'属性<br />'; 71 echo '且值是',$b,'<br />'; 72 } 73 } 74 echo '<hr />'; 75 $hmm = new Stu(); 76 $hmm->aaa = 111; 77 $hmm->money = 55; 78 $hmm->age = 34; 79 print_r($hmm); 80 81 echo '<br />'; 82 $hmm->name = 'lily'; 83 print_r($hmm); 84 85 /*** 86 总结: 87 当为无权操作或不存在的属性赋值时,__set()自动调用 88 且自动传2个参数,分别是属性名,属性值 89 比如 90 $hmm->age = 30 ---无权--->__set(age,30); 91 ***/ 92 93 echo '<hr />'; 94 class Dog{ 95 protected $bone = '猪腿骨'; 96 public $leg = 4; 97 public function __unset($p){ 98 echo '你想去掉我的',$p,'<br />'; 99 } 100 public function __isset($p){ 101 echo '你想判断我的',$p,'属性存不存在<br />'; 102 return 1; 103 } 104 } 105 $hua = new Dog(); 106 if (isset($hua->leg)) { 107 echo $hua->leg,'<br />'; 108 } 109 if (isset($hua->tail)) { 110 echo '有tail属性'; 111 }else { 112 echo '没有tail属性'; 113 } 114 /*** 115 __isset()方法, 116 当isset()判断对象不可见的属性(private/protected/)或不存在的属性,__isset()会自动运行 117 118 问:isset($obj->xyz)属性,为真,能说明类声明了一个xyz属性吗? 119 答:不能 120 121 ***/ 122 echo '<hr />'; 123 echo 'unset测试'; 124 print_r($hua); 125 unset($hua->leg); 126 print_r($hua); 127 128 unset($hua->tail); 129 unset($hua->bone); 130 131 /*** 132 总结: 133 当用unset销毁对象的不可见属性/不存在属性时,__unset()自动运行 134 unset($hua->tail)--不存在tail属性-->__unset(tail) 135 ***/ 136 137 /*** 138 __call 139 当调用一个不可访问的方法(未定义的,或不可见的)时,__call自动运行 140 __callStatic 141 当调用一个不可访问的静态方法(未定义的,或不可见的),__callStatic自动运行 142 ***/ 143 class Human { 144 public function hello(){ 145 echo 'hello <br />'; 146 } 147 148 private function t(){ 149 150 } 151 static public function __callStatic($method,$arguments){ 152 echo '你想调用一个无权调用或不存在的静态方法',$method,'<br />'; 153 echo '调用时还传来了参数<br />'; 154 print_r($arguments); 155 echo '<br />'; 156 157 } 158 public function __call($method,$arguments){ 159 160 echo '你想调用一个不存在的方法',$method,'<br />'; 161 echo '调用时还传来了参数<br />'; 162 print_r($arguments); 163 echo '<br />'; 164 } 165 166 } 167 168 $lisi = new Human(); 169 $lisi->hello(); 170 $lisi->say(1,2,3);//调用一个未定义的方法Fatal error: Call to undefined method Human::say() 171 $lisi->t('a','b','c'); 172 /* 173 $lisi->say(1,2,3);---没有say()方法--->__call('say',array(1,2,3))运行 174 */ 175 Human::cry('痛苦','嚎哭','鬼哭'); 176 177 /*** 178 Human::cry(1,2,3);---没有cry()静态方法--->__callStatic('cry',array(1,2,3))运行 179 ***/ 180 /* 181 为什么__callStatic()这个魔术方法和其他的魔术方法的颜色不一样? 182 183 答:这个方法是PHP5.3里才添加的,比较新 184 可能老版本的编辑器的语法文件里还没有 185 */ 186 187 ?>