PHP魔术方法和魔术常量介绍及使用实例--测试
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()
构造函数和析构函数应该不陌生,他们在对象创建和消亡时被调用。例如我们需要打开一个文件,在对象创建时打开,对象消亡时关闭
class FileRead { protected $handle = NULL; function __construct(){ $this->handle = fopen('test.php','r'); var_dump(@fread($this->handle,"100")); } function __destruct(){ fclose($this->handle); var_dump(@fread($this->handle,"100")); } } $a = new FileRead(); unset($a); class TmpFileRead extends FileRead { function __construct(){ parent::__construct(); } function __destruct(){ parent::__destruct(); } } $b = new TmpFileRead(); unset($b); /*** 查看源码: string(100) "<?php class FileRead { protected $handle = NULL; function __construct(){ $this->h" bool(false) string(100) "<?php class FileRead { protected $handle = NULL; function __construct(){ $this->h" bool(false) ***/ exit;
__call()
和__callStatic()
在对象中调用一个不可访问方法时会调用这两个方法,后者为静态方法。这两个方法我们在可变方法(Variable functions)调用中可能会用到。
class MethodTest { //没有这两个魔术方法 对应调用会提示没有这个方法 public function __call ($name, $arguments) { echo "Calling object method '$name' <br />"; print_r($arguments); echo "<br />"; } public static function __callStatic ($name, $arguments) { echo "Calling static method '$name' <br />"; print_r($arguments); echo "<br />"; } } $obj = new MethodTest; $obj->runTest('in object context',[3,3,4,5,6],[123,123]); MethodTest::runTest('in static context',[34,54,65,65]); /** Calling object method 'runTest' Array ( [0] => in object context [1] => Array ( [0] => 3 [1] => 3 [2] => 4 [3] => 5 [4] => 6 ) [2] => Array ( [0] => 123 [1] => 123 ) ) Calling static method 'runTest' Array ( [0] => in static context [1] => Array ( [0] => 34 [1] => 54 [2] => 65 [3] => 65 ) ) **/ exit;
__get()
,__set()
,__isset()
和__unset()
当get/set一个类的成员变量时调用这两个函数。例如我们将对象变量保存在另外一个数组中,而不是对象本身的成员变量
在给不可访问属性赋值时,__set() 会被调用。
读取不可访问属性的值时,__get() 会被调用。
当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被调用。
当对不可访问属性调用 unset() 时,__unset() 会被调用。
class MethodTest { private $data = array(); public function show() { print_r($this->data); } public function __set($name, $value){ $this->data[$name] = $value; } public function __get($name){ echo $name; if(array_key_exists($name, $this->data)) return $this->data[$name]; return NULL; } public function __isset($name){ echo "123<br />"; return isset($this->data[$name]); } public function __unset($name){ echo "321<br />"; unset($this->data[$name]); } } $a = new MethodTest(); $a->bb = 'bb'; $b = $a->bb; isset($a->cc); unset($a->dd); /**** bb123 321 Array ( [bb] => bb ) ***/ exit;