PHP中魔术方法的定义是把以两个下划线__开头的方法称为魔术方法,这些魔术方法在PHP中的作用是非常重要的,下面我们就来看看这些魔术方法的实例。
魔术方法:
__construct(),类的构造函数__destruct(),类的析构函数__call(),在对象中调用一个不可访问方法时调用__callStatic(),用静态方式中调用一个不可访问方法时调用__get(),获得一个类的成员变量时调用__set(),设置一个类的成员变量时调用__isset(),当对不可访问属性调用isset()或empty()时调用__unset(),当对不可访问属性调用unset()时被调用。__sleep(),执行serialize()时,先会调用这个函数__wakeup(),执行unserialize()时,先会调用这个函数__toString(),类被当成字符串时的回应方法__invoke(),调用函数的方式调用一个对象时的回应方法__set_state(),调用var_export()导出类时,此静态方法会被调用。__clone(),当对象复制完成时调用
__construct()和__destruct()
构造函数和析构函数应该不陌生,他们在对象创建和消亡时被调用。例如我们需要打开一个文件,在对象创建时打开,对象消亡时关闭
<?phpclass FileRead{ protected $handle = NULL; function __construct(){ $this->handle = fopen(...); } function __destruct(){ fclose($this->handle); }}?>
这两个方法在继承时可以扩展,例如:
<?phpclass TmpFileRead extends FileRead{ function __construct(){ parent::__construct(); } function __destruct(){ parent::__destruct(); }}?>
__call()和__callStatic()
在对象中调用一个不可访问方法时会调用这两个方法,后者为静态方法。这两个方法我们在可变方法(Variable functions)调用中可能会用到。
<?phpclass MethodTest{ public function __call ($name, $arguments) { echo "Calling object method '$name' ". implode(', ', $arguments). "\n"; } public static function __callStatic ($name, $arguments) { echo "Calling static method '$name' ". <mark>(本文来)源gaodaimacom搞#^代%!码&网(</mark><pre>搞gaodaima代码
implode(', ', $arguments). "\n"; }} $obj = new MethodTest;$obj->runTest('in object context');MethodTest::runTest('in static context');?>
__get(),__set(),
__get属性是当访问对象中的属性不存在或者非公有属性的时候自动加载__get方法,参数只有一个name值,就是访问对象中
属性的名字。
__set是当给对象中一个属性赋值的时候如果该属性不存在或者非公有属性的时候就会自动加载__set方法。参数有两个,参数1是访问对象中不可被调用属性的名字,参数2是将要给赋值所传的参数,可以是数组,也可以是字符串
都具有公共可见性,非静态,举个小栗子方便理解:
<?php/** * 清晰的认识__get() __set() */class Example { //公有的属性 public $public = 'pub' ; //受保护的 - 子类中该属性可用 protected $protected = 'pro'; //私有的 - 只能此类使用此属性 private $private = 'pri'; //当访问对象中的属性不存在或者非公有属性的时候自动加载__get()方法 public function __get($name){ return '调用__get()方法:'.$name; } //当给对象的一个属性赋值的时候如果该属性不存在或者是非公有属性则自动加载__set()方法 public function __set($name,$value){ echo "\nname:".$name.',value:'.$value."\n"; }}$example = new Example;echo '<pre>';echo $example->public."\n";echo $example->protected."\n";echo $example->private."\n";echo $example->other."\n";echo '<hr>';$example->public = 'lic'; //这个赋值成功所有没有显示$example->protected = 'tec';$example->private = 'vat';$example->other = 'er';echo '<br/>';