一:下面涉及魔术方法:
1,__isset();在类外部检测一个属性是否存在时自动调用:
2,__unset();在类外部销毁一个私有或者受保护的属性时自定调用;
3,__toString();将对象当做字符串来访问时候自动调用;
4,__invoke();将对象当做函数来执行时自动调用:
5,__clone();对象克隆时候自动调用;
class Demo{ private $name; private $age; public $site='PHP中文网'; function __construct($name,$age){ $this->name=$name; $this->age=$age; } function __isset($proName){//在类外部检测一个不存在的属性是就会显示有; return isset($proName); } function __unset($proName){ if($this->name=='Peter Zhu'){//如果当前name 是Peter Zhu 不允许销毁 echo '<h3 style="color:red">不允许注销</h3>'; } unset($proName); } function __toString(){ return '<h2 style="color:green">我是一个对象不能当做字符串来访问~~~</h2>'; } function __invoke($value){ return '<h2 style="color:green">我是一个对象不能当做函数来调用~~~'.$value.'</h2>'; } public function __clone(){//禁用克隆 } } $obj=new Demo('Peter Zhu',39); echo isset($obj->name)?'有':'无'.'<br>';//直接输出页面会显示无,这个时候需要使用__isset()方法 echo isset($obj->age)?'有':'无'; unset($obj->name);//直接销毁会报错,这个时候需要用到方法__unset();使用__unset()方法后会弹出红色字///体不允许注销 /*__toString():对象当做字符串来访问; * __invoke():对象当做函数来访问: * __clone():对象克隆时自动调用 */ $obj1=$obj; //对象的复制相当于给这个对象起了个别名,在$obj1中修改对象的属性,$obj中的对象属性也随之改变 $obj1->site='www.php.cn/php2/'; echo $obj->site,'<br>'; //演示对象克隆 echo '<h2>对象克隆值传递</h2><br>'; echo $obj->site='PHP中文网'; $obj2=clone($obj); $obj2->site='www.php.cn/php2.cn/'; echo $obj2->site,'<br>'; echo $obj->site,'<br>';//$obj中的site 属性值没有被改变 echo $obj;//把对象当做字符串来访问,将对象当字符串来访问,会提示错误,不允许将对象当字符串输出 //如果在类中有一个__toString()方法来处理就不会了 echo $obj('php.cn');//把对象当做函数来执行会报错,如果类中有__invoke()方法就不会了; $obj3=clone(new Demo('Peter Zhu',30)); //echo $obj3->name;//克隆失效
总结:克隆对象,就是给当前对象创建一个双胞胎,尽管看上去一样,但却是二个完全独立互不影响的实体
克隆有时很有用,但更多的时候,会带来一些副作用,例如对于一个类来说,创建太多的实例是没有意义的,
所以需要禁用对象克隆,例如常用用的:单例模式,就必须禁用克隆的方式来创建新对象
这时可以给当前类添加一个魔术方法:__clone(),使类外部克隆对象操作失效