来自:lqx651 > 馆藏分类
配色: 字号:
PHP魔术函数
2012-02-23 | 阅:  转:  |  分享 
  
什么是魔术函数?对于__开头的函数就命名为魔术函数,此类函数都在特定的条件下触发的.比如:__set()__get()等在设置或取不存在的属性时候触发.有那些魔术函数呢?总的来说,有下面几个魔术函数__construct()__destruct()__get()__set()__isset()__unset()__call()__callStatic()__sleep()__wakeup()__toString()__set_state()__clone()__autoload()__construct()当实例化一个对象的时候,这个对象的这个方法首先被调用。__destruct()当删除一个对象或对象操作终止的时候,调用该方法。复制代码代码如下:classtest1{publicfunction__construct(){var_dump(__function__);}publicfunction__destruct(){var_dump(__function__);}}$t1=newtest1;unset($t1);

__get当试图读取一个并不存在的属性的时候被调用。__set当试图向一个并不存在的属性写入值的时候被调用。__isset当试图检测一个并不存在的属性时候被调用。__unset当试图取消一个并不存在的属性时候被调用。复制代码代码如下:classtest2{public$name3;publicfunction__set($key,$value){var_dump(__function__.''KEY:''.$key.''Value:''.$value);}publicfunction__get($key){var_dump(__function__.''KEY:''.$key);}publicfunction__isset($key){var_dump(__function__.''KEY:''.$key);}publicfunction__unset($key){var_dump(__function__.''KEY:''.$key);}}$t=newtest2;$t->name="steven";$t->name2;$t->name3;isset($t->name2);isset($t->name3);unset($t->name4);

__sleep当进行序列化对象时候调用__wakeup当进行反序列对象时候调用需要注意一点:

www.nbyqjx.com?1.__sleep()必须返回一个数组或者对象(一般返回的是$this),返回的值将会被用来做为序列化的值。如果不返回这个值,则序列化失败。这也意味着反序列化将不会触发__wakeup事件。2.序列化会保存默认赋值的属性.如果要通过实例化赋值的内容,则需要属性在__sleep()返回数组的指定.如$id与$id2的区别.复制代码代码如下:classtest3{public$name="steven";public$id="1";public$id2;publicfunction__sleep(){var_dump(__function__);//序列化不成功.没有返回值.反序列也失败//returnarray("name");//序列化成功.有返回值.反序列成功.id2属性能被恢复//returnarray("name","id2");//序列化成功.有返回值.反序列成功.id2属性不能被恢复returnarray("name");}publicfunctiontestEcho(){var_dump($this->name);var_dump($this->id);var_dump($this->id2);}publicfunction__wakeup(){var_dump(__function__);$this->testEcho();}}$t3=newtest3;$t3->id2=uniqid();$t3s=serialize($t3);unserialize($t3s);

__toString当直接打印一个对象的时候,这个方法将会被调用复制代码代码如下:classtest4{publicfunction__toString(){return"toString";}}$t4=newtest4();echo$t4;print$t4;var_dump($t4);print_r($t4);

__call($func,$param)当尝试调用一个不存在的方法的时候被调用.这个方法必须有两个参数,第一个为调用的方法名,第二个是一个被调用方法的参数数组。需要注意的是,当你在一个子类调用父类的private的方法,或者在实例里调用类的非protect方法的时候,并不会调用__call()复制代码代码如下:classtest5{publicfunction__call($func,$param){var_dump(''Function:''.$func);var_dump($param);}}$t5=newtest5;$t5->echoTest(''xx'',''xx'',''xx'');

__callStatic()当尝试调用一个不存在的静态方法的时候被调用这个方法必须有两个参数,第一个为调用的方法名,第二个是一个被调用方法的参数数组。在PHP5.3中出现复制代码代码如下:classtest51{publicfunction__callStatic($fun,$param){var_dump(''Function:''.$func);var_dump($param);}}test51::test(''xx'',''xx'',''xx'');

__set_state()当用var_export导出实例的时候被调用.此方法有一个参数,为包含所导出的实例的所有成员属性的一个数组复制代码代码如下:classtest6{publicfunction__set_state($arr){var_dump($arr);}}$t6=newtest6;$t6->age="12";var_export($t6,true);var_export($t6);eval(''$b=''.var_export($t6,true).'';'');print_r($b);

__clone()当克隆实例时候被调用.注意:1.在php5里,对象间的赋值总是以地址引用来传递的.2.如果要以实际值来传递,则需要用到clone关键词3.clone的只是实例。如果实例中的某个成员属性也是个实例,那么这个成员属性还是会以引用方法被传递到新的实例。//对象间的赋值总是以地址引用来传递的.$t71$t72的age属性是一样的.

复制代码代码如下:classtest71{public$age=10;}$t71=newtest71();$t72=$t71;var_dump($t71->age);$t71->age=12;var_dump($t71->age);var_dump($t72->age);//如果要以实际值来传递,则需要用到clone关键词$t73=clone$t71;$t71->age=13;var_dump($t71->age);var_dump($t73->age);//如果实例中的某个成员属性也是个实例,那么这个成员属性还是会以引用方法被传递到新的实例。

复制代码代码如下:classtest74{public$age=10;public$sub=null;}classtest75{public$age=11;}$i=newtest74;$i->sub=newtest75();$i1=clone$i;var_dump($i1->sub->age);$i->sub->age=12;var_dump($i1->sub->age);

//$i和$i1虽然不是指向同一个实例,但是它们的成员属性$sub却是指向同一个实例。这时候,我们必须借助__clone这个方法来对$sub进行复制。//$i2和$3指向不同实例.成员属性$sub也指向不同实例.复制代码代码如下:classtest76{public$age=10;public$sub=null;publicfunction__clone(){$this->sub=clone$this->sub;}}$i2=newtest76();$i2->sub=newtest75();$i3=clone$i2;$i2->sub->age=15;var_dump($i3->sub->age);

__autoload()函数.当创建一个实例化的时候,如果对应的类不存在,则会被调用复制代码代码如下:function__autoload($class){if($class=="test8"){require_oncedirname(__FILE__).''/class8.php'';}}spl_autoload();$t8=newtest8;var_dump($t8->age);



献花(0)
+1
(本文系lqx651首藏)