PHP中的魔术方法
1 /*** 2 魔术方法: 3 是指某些情况下,会自动调用的方法,称为魔术方法 4 PHP面向对象中,提供了这几个魔术方法, 5 他们的特点 都是以双下划线__开头的 6 __construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state() 和 __clone() 7 __construct :构造方法 8 __destruct :析构方法 9 __clone() :克隆方法,当对象被克隆时,将会自动调用 10 ***/ 11 //__clone() :克隆方法,当对象被克隆时,将会自动调用 12 class Human { 13 public $age = 22; 14 public function __clone() { 15 echo '有人克隆我!假冒'; 16 } 17 } 18 $lisi = new Human(); 19 $zhangsan = clone $lisi; 20 /* 21 结果: 22 有人克隆我!假冒 23 */
1 //魔术方法__get 2 class Human { 3 private $money = '30两'; 4 protected $age = 23; 5 public $name = 'lily'; 6 public function __get($p) { 7 echo '你想访问我的',$p,'属性<br/>'; 8 } 9 } 10 $lily = new Human(); 11 // echo $lily->name; //lily 12 echo $lily->age; // 你想访问我的age属性 13 echo $lily->money; // 你想访问我的money属性 14 echo $lily->friend; // 你想访问我的friend属性 15 /* 16 可以总结出: 17 当我们调用一个权限上不允许调用的属性,和不存在的属性时, 18 __get魔术方法会自动调用, 19 并且自动传参,参数值是属性名. 20 流程: 21 $lily->age--无权-->__get(age); 22 $lily->friend--没有此属性-->__get('friend'); 23 生活中,你帮别人看守小卖店 24 买牙刷--->好,给你牙刷 25 买毛巾--->好,给你毛巾 26 这个POS机挺好---> (pos是商店的工具,私有的,不卖的:"你无权买"), 但是我们用__get方法, 27 就有一个友好的处理机会. 28 系统会直接报错,甚至fatal error,通过__get,我们就能自定义用户访问时,的处理行为. 29 */ 30 echo '<br />'; 31 32 //设置没有的属性 33 $lily->aaa = 111; 34 $lily->bbb = 222; 35 print_r($lily); 36 37 /* 38 结果 39 Human Object 40 ( 41 [money:Human:private] => 30两 42 [age:protected] => 23 43 [name] => lily 44 [aaa] => 111 //添加的属性 45 [bbb] => 222 //添加的属性 46 ) 47 48 */ 49 50 /* 51 竟然给加上了. 52 其实,对象就是一个属性集,在js中更明显. 53 如果这么随便就能加了属性,导致这个对象属性过多,不好管理 54 */
1 <p><?<a href="http://lib.csdn.net/base/php" class="replace_word" title="PHP知识库" target="_blank" style="color:#df3434; font-weight:bold;">PHP</a> 2 //魔术方法__set 3 class Stu { 4 private $money = '30两'; 5 protected $age = 23; 6 public $name = 'Hmm'; 7 public function __set($a,$b) { 8 echo '你想设置我的',$a,'属性','<br />'; 9 echo '且值是',$b,'<br />'; 10 } 11 } 12 echo '<hr />'; 13 $hmm = new Stu(); 14 $hmm->aaa = 111; //你想设置我的aaa属性且值是111 15 $hmm->money = '40两';//你想设置我的money属性且值是40两 16 $hmm->age = '28'; //你想设置我的age属性且值是28 17 print_r($hmm); 18 /* 19 结果 20 Stu Object 21 ( 22 [money:Stu:private] => 30两 23 [age:protected] => 23 24 [name] => Hmm 25 ) 26 */ 27 $hmm->name = 'HanMM'; 28 print_r($hmm); 29 /* 30 结果 31 Stu Object 32 ( 33 [money:Stu:private] => 30两 34 [age:protected] => 23 35 [name] => HanMM 36 )</p><p>*/ 37 /* 38 如上,总结出 __set的作用 39 当为无权操作的属性赋值时, 40 或不存在的属性赋值时, 41 __set()自动调用 42 且自动传2个参数 属性 属性值 43 例: 44 $hmm->age = 28 ---无权---> __set('age',28); 45 */ </p><p>?></p>
1 //魔术方法__isset __unset 2 echo '<hr />'; 3 class Dog { 4 public $leg = 4; 5 protected $bone = '猪腿骨'; 6 public function __isset($p) { 7 echo '你想判断我的',$p,'属性存不存在<br />'; 8 return 1; 9 } 10 public function __unset($p) { 11 echo '你想去掉我的',$p,'?!<br />'; 12 } 13 } 14 $hua = new Dog(); 15 if(isset($hua->leg)) { 16 echo $hua->leg,'<br/>'; 17 } 18 /* 19 结果:4 20 */ 21 if(isset($hua->tail)) { 22 echo '有tail属性'; 23 } else { 24 echo '没有tail'; 25 } 26 /* 27 结果: 28 你想判断我的tail属性存不存在 29 有tail属性 30 */ 31 32 /*** 33 __isset() 方法, 34 当 用isset() 判断对象不可见的属性时(protected/private/不存在的属性) 35 会引发 __isset()来执行 36 问: isset($obj->xyz) 属性,为真, 37 能说明 类声明了一个xyz属性吗? 38 答:不能 39 ***/ 40 echo '<hr />'; 41 echo '__unset测试<br/>'; 42 print_r($hua); 43 /* 44 结果: 45 __unset测试 46 Dog Object 47 ( 48 [leg] => 4 49 [bone:protected] => 猪腿骨 50 ) 51 52 */ 53 unset($hua->leg); 54 print_r($hua); 55 /* 56 结果: 57 Dog Object 58 ( 59 [bone:protected] => 猪腿骨 60 ) 61 */ 62 unset($hua->tail); 63 unset($hua->bone); 64 /* 65 结果: 66 你想去掉我的tail?! 67 你想去掉我的bone?! 68 */ 69 /*** 70 __unset()方法 71 当 用unset 销毁对象的不可见属性时, 72 会引发 __unset(); 73 unset($hua->tail)----没有tail属性---->__unset('tail'); 74 ***/