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 ***/