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 ?>

 

 

  


  

 

posted @ 2015-05-29 20:20  museluo  阅读(190)  评论(0编辑  收藏  举报